仿射密码技术:
M= Dk(c)=k3(c- k2) mod n(其中k3为k1逆元)
(1)0<k1<n
(2)k1与n互素,即要满足gcd(k1, n)=1,否则不存在模逆元,不能正确解密
所以即满足乘法密码技术的要求,又满足加法密码的要求,如复合函数一般
K1 K2为密钥。当K1=0时,仿射密码即为乘法密码技术,当K1=1时,即为移位替换密码(加法密码)
乘法密码的密码空间大小是φ(n),φ(n)是欧拉函数。
当n为26字母,则与26互素的数是1、3、5、7、9、11、15、17、19、21、23、25,即φ(n)=12 因此乘法密码的密钥空间为12。
注意:K1=1时 加密变换为恒等变换(即无变化)
测试案例如下:
import java.util.ArrayList;
import java.util.Scanner;
public class 仿射密码技术 {
public static int x=0,y=0;
public static ArrayList<Integer> SecretPlace=new ArrayList();
public static int gcd(int a,int b){
return b>0?gcd(b,a%b):a;
}
public static int ex_gcd(int a,int b){
if(b==0)
{
x=1;y=0;
return a;
}
int q=ex_gcd(b,a%b);
int t=x;x=y;y=t-a/b*y;
return q;
}
public static void CountSecretPlace(int n){
SecretPlace.add(1);
for(int i=2;i<n;i++){
if(gcd(i, n)==1)
SecretPlace.add(i);
}
}
public static void main(String[] args) {
int k1,k2=0;
Scanner scan=new Scanner(System.in);
System.out.println("第一行输入密码表总数n\n"
+ "第二行输入各明文字符\n"
+ "第三行输入待加密明文");
int n=scan.nextInt();
char CharArrays[]=new char[n];
CharArrays=scan.next().toCharArray();
scan.nextLine();
String normalStr=scan.nextLine();
CountSecretPlace(n);
System.out.println("密钥空间如下,您可选择其中一个值作为乘法密钥K1");
System.out.println(SecretPlace);
k1=scan.nextInt();
while(!SecretPlace.contains(k1)){
System.out.println("只能选择密钥空间中的密钥值!请重新选择");
k1=scan.nextInt();
}
System.out.println("请选择加法密钥K2,0=<k2<n");
k2=scan.nextInt();
while(k2<0||k2>=n){
System.out.println("请重新选择加法密钥K2,0=<k2<n");
k2=scan.nextInt();
}
ex_gcd(k1, n);
int out=(x+n)%n;
System.out.println("您选择的乘法密钥模逆元为:"+out);
String splitStrs[]=normalStr.split(" ");
ArrayList<Character> templist=new ArrayList<>();
System.out.println("加密后如下:");
for (int j = 0; j < splitStrs.length; j++) {
char normalChars[]=splitStrs[j].toCharArray();
for (int p = 0; p < normalChars.length; p++) {
int t=((normalChars[p]-'a')*k1+k2)%n;
normalChars[p]=CharArrays[t];//加密
System.out.print(normalChars[p]);
int tt=(t+n-k2)%n;
normalChars[p]=CharArrays[tt*out%n];//解密
templist.add(normalChars[p]);
}
System.out.print(" ");
templist.add(' ');
}
System.out.println("\n解密后如下:");
for(Character o:templist){
System.out.print(o);
}
}
}
运行结果如下:
第一行输入密码表总数n
第二行输入各明文字符
第三行输入待加密明文
26
abcdefghijklmnopqrstuvwxyz
a man liberal in his views
密钥空间如下,您可选择其中一个值作为乘法密钥K1
[1, 3, 5, 7, 9, 11, 15, 17, 19, 21, 23, 25]
1
请选择加法密钥K2,0=<k2<n
3
您选择的乘法密钥模逆元为:1
加密后如下:
d pdq olehudo lq klv ylhzv
解密后如下:
a man liberal in his views
(加法密码+乘法密码)
(可先参见加法密码与乘法密码原理)
M= Dk(c)=k3(c- k2) mod n(其中k3为k1逆元)
(1)0<k1<n
(2)k1与n互素,即要满足gcd(k1, n)=1,否则不存在模逆元,不能正确解密
所以即满足乘法密码技术的要求,又满足加法密码的要求,如复合函数一般
K1 K2为密钥。当K1=0时,仿射密码即为乘法密码技术,当K1=1时,即为移位替换密码(加法密码)
乘法密码的密码空间大小是φ(n),φ(n)是欧拉函数。
当n为26字母,则与26互素的数是1、3、5、7、9、11、15、17、19、21、23、25,即φ(n)=12 因此乘法密码的密钥空间为12。
注意:K1=1时 加密变换为恒等变换(即无变化)
测试案例如下:
import java.util.ArrayList;
import java.util.Scanner;
public class 仿射密码技术 {
public static int x=0,y=0;
public static ArrayList<Integer> SecretPlace=new ArrayList();
public static int gcd(int a,int b){
return b>0?gcd(b,a%b):a;
}
public static int ex_gcd(int a,int b){
if(b==0)
{
x=1;y=0;
return a;
}
int q=ex_gcd(b,a%b);
int t=x;x=y;y=t-a/b*y;
return q;
}
public static void CountSecretPlace(int n){
SecretPlace.add(1);
for(int i=2;i<n;i++){
if(gcd(i, n)==1)
SecretPlace.add(i);
}
}
public static void main(String[] args) {
int k1,k2=0;
Scanner scan=new Scanner(System.in);
System.out.println("第一行输入密码表总数n\n"
+ "第二行输入各明文字符\n"
+ "第三行输入待加密明文");
int n=scan.nextInt();
char CharArrays[]=new char[n];
CharArrays=scan.next().toCharArray();
scan.nextLine();
String normalStr=scan.nextLine();
CountSecretPlace(n);
System.out.println("密钥空间如下,您可选择其中一个值作为乘法密钥K1");
System.out.println(SecretPlace);
k1=scan.nextInt();
while(!SecretPlace.contains(k1)){
System.out.println("只能选择密钥空间中的密钥值!请重新选择");
k1=scan.nextInt();
}
System.out.println("请选择加法密钥K2,0=<k2<n");
k2=scan.nextInt();
while(k2<0||k2>=n){
System.out.println("请重新选择加法密钥K2,0=<k2<n");
k2=scan.nextInt();
}
ex_gcd(k1, n);
int out=(x+n)%n;
System.out.println("您选择的乘法密钥模逆元为:"+out);
String splitStrs[]=normalStr.split(" ");
ArrayList<Character> templist=new ArrayList<>();
System.out.println("加密后如下:");
for (int j = 0; j < splitStrs.length; j++) {
char normalChars[]=splitStrs[j].toCharArray();
for (int p = 0; p < normalChars.length; p++) {
int t=((normalChars[p]-'a')*k1+k2)%n;
normalChars[p]=CharArrays[t];//加密
System.out.print(normalChars[p]);
int tt=(t+n-k2)%n;
normalChars[p]=CharArrays[tt*out%n];//解密
templist.add(normalChars[p]);
}
System.out.print(" ");
templist.add(' ');
}
System.out.println("\n解密后如下:");
for(Character o:templist){
System.out.print(o);
}
}
}
运行结果如下:
第一行输入密码表总数n
第二行输入各明文字符
第三行输入待加密明文
26
abcdefghijklmnopqrstuvwxyz
a man liberal in his views
密钥空间如下,您可选择其中一个值作为乘法密钥K1
[1, 3, 5, 7, 9, 11, 15, 17, 19, 21, 23, 25]
1
请选择加法密钥K2,0=<k2<n
3
您选择的乘法密钥模逆元为:1
加密后如下:
d pdq olehudo lq klv ylhzv
解密后如下:
a man liberal in his views
本文探讨了仿射密码,一种结合加法和乘法的古老加密技术。通过深入理解加法密码和乘法密码的原理,可以更好地了解这种密码系统的安全性及其在信息安全中的应用。
897

被折叠的 条评论
为什么被折叠?



