java - 如何使用 RSA 方法加密/解密文本?
问题描述
我有一个简单的 java 代码,它使用 RSA 算法加密和解密数字
如果有人可以帮助我让这段代码从用户那里读取一个文本(字符串)并解密它而不是仅仅用数字而是以一种简单的方式解密,这样我就可以在之后为代码绘制流程图:)
https://codedost.com/css/java-program-rsa-algorithm/
import java.util.*;
import java.math.*;
public class RSA {
public static void main(String args[]) {
Scanner sc = new Scanner(System.in);
int p, q, n, z, d = 0, e, i;
System.out.println("Enter the number to be encrypted and decrypted");
int msg = sc.nextInt();
double c;
BigInteger msgback;
System.out.println("Enter 1st prime number p");
p = sc.nextInt();
System.out.println("Enter 2nd prime number q");
q = sc.nextInt();
n = p * q;
z = (p - 1) * (q - 1);
System.out.println("the value of z = " + z);
for (e = 2; e < z; e++) {
if (gcd(e, z) == 1) // e is for public key exponent
{
break;
}
}
//e should be in the range 1-z
System.out.println("the value of e = " + e);
// calculate d
for (i = 0; i <= 9; i++) {
int x = 1 + (i * z);
if (x % e == 0) //d is for private key exponent
{
d = x / e;
break;
}
}
System.out.println("the value of d = " + d);
c = (Math.pow(msg, e)) % n;
//Encryptin C = msg ^e mod n
System.out.println("Encrypted message is : -");
System.out.println(c);
//converting int value of n to BigInteger
BigInteger N = BigInteger.valueOf(n);
//converting float value of c to BigInteger
BigInteger C = BigDecimal.valueOf(c).toBigInteger();
msgback = (C.pow(d)).mod(N);
//Decrypt , P = Cˆd mod N , msgback = P
System.out.println("Derypted message is : -");
System.out.println(msgback);
}
static int gcd(int e, int z) {
if (e == 0) {
return z;
} else {
return gcd(z % e, e);
}
}
}
解决方案
由于您已经为单个号码实现了加密和解密,您可以轻松扩展它并为更长的消息提供支持。实际上,您需要的唯一更改是执行相同的操作 N 次(对于输入消息中的每个字符)。看看下面的代码:
import java.util.*;
import java.math.*;
public class Rsa {
private static final Scanner sc = new Scanner(System.in);
private int p, q, n, z, d = 0, e, i;
public Rsa() {
System.out.println("Enter 1st prime number p");
p = sc.nextInt();
System.out.println("Enter 2nd prime number q");
q = sc.nextInt();
n = p * q;
z = (p - 1) * (q - 1);
System.out.println("the value of z = " + z);
for (e = 2; e < z; e++) {
if (gcd(e, z) == 1) // e is for public key exponent
{
break;
}
}
//e should be in the range 1-z
System.out.println("the value of e = " + e);
// calculate d
for (i = 0; i <= 9; i++) {
int x = 1 + (i * z);
if (x % e == 0) //d is for private key exponent
{
d = x / e;
break;
}
}
System.out.println("the value of d = " + d);
}
private static int gcd(int e, int z) {
if (e == 0) {
return z;
} else {
return gcd(z % e, e);
}
}
double encrypt(int msg) {
//Encrypting C = msg ^e mod n
return (Math.pow(msg, e)) % n;
}
double[] encrypt(String msg) {
int[] charactersAsNumbers = new int[msg.length()];
for(int i = 0; i < msg.length(); i++) {
charactersAsNumbers[i] = msg.codePointAt(i);
}
System.out.println("Plain text as sequence of numbers: " + Arrays.toString(charactersAsNumbers));
double[] encryptedMsg = new double[msg.length()];
for(int i = 0; i < charactersAsNumbers.length; i++) {
encryptedMsg[i] = encrypt(charactersAsNumbers[i]);
}
return encryptedMsg;
}
BigInteger decrypt(double encrypted) {
//converting int value of n to BigInteger
BigInteger N = BigInteger.valueOf(n);
//converting float value of c to BigInteger
BigInteger C = BigDecimal.valueOf(encrypted).toBigInteger();
//Decrypt , P = Cˆd mod N , msgback = P
return (C.pow(d)).mod(N);
}
String decrypt(double[] encrypted) {
StringBuilder builder = new StringBuilder();
for(double encryptedCharacter: encrypted) {
BigInteger decryptedCharacter = decrypt(encryptedCharacter);
builder.append(Character.toChars(decryptedCharacter.intValue()));
}
return builder.toString();
}
public static void main(String args[]) {
System.out.println("Enter the text to be encrypted and decrypted");
String msg = sc.nextLine();
Rsa rsa = new Rsa();
double[] c = rsa.encrypt(msg);
System.out.println("Encrypted message is: " + Arrays.toString(c));
String msgBack = rsa.decrypt(c);
System.out.println("Decrypted message is: " + msgBack);
}
}
我在这里所做的是:
- 重载
encrypt
和decrypt
方法。现在它们支持更长的消息;encrypt
接受String
参数并返回double[]
,decrypt
接受double[]
并返回String
- 逻辑转移到方法而不改变原始数据类型和一般流程
我知道给定的解决方案不是最优的,但我猜在这种情况下性能和代码风格对你来说并不重要。
希望它可以帮助您解决您的问题。
编辑:我稍微改进了日志,这是示例输出(和输入):
Enter the text to be encrypted and decrypted
Secret.
Enter 1st prime number p
13
Enter 2nd prime number q
19
the value of z = 216
the value of e = 5
the value of d = 173
Plain text as sequence of numbers: [83, 101, 99, 114, 101, 116, 46]
Encrypted message is: [239.0, 43.0, 112.0, 95.0, 43.0, 51.0, 50.0]
Decrypted message is: Secret.