在Java中使用RSA算法加密字符串时出现问题
我正在尝试采用 RSA 算法来加密 String 对象,但似乎 BigInteger ->字符串和字符串 -> BigInteger 转换无法正常工作。这是我的代码:
public class RSAEncryptor {
private BigInteger n, d, e;
public RSAEncryptor(int bitlen) {
SecureRandom r = new SecureRandom();
BigInteger p = new BigInteger(bitlen / 2, 100, r);
BigInteger q = new BigInteger(bitlen / 2, 100, r);
n = p.multiply(q);
BigInteger m = (p.subtract(BigInteger.ONE)).multiply(q.subtract(BigInteger.ONE));
e = new BigInteger("3");
while (m.gcd(e).intValue() > 1) {
e = e.add(new BigInteger("2"));
}
d = e.modInverse(m);
}
public String encrypt(String message) {
BigInteger plaintext = new BigInteger(message.getBytes());
return new String(plaintext.modPow(e, n).toByteArray());
}
public String decrypt(String message) {
BigInteger plaintext = new BigInteger(message.getBytes());
return new String(plaintext.modPow(d, n).toByteArray());
}
}
public class Main {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
RSAEncryptor encryptor = new RSAEncryptor(64);
String source = "1";
String crypted = encryptor.encrypt(source);
System.out.println(crypted);
String decrypted = encryptor.decrypt(crypted);
System.out.println(decrypted);
}
}
它打印的不是预期的内容,奇怪的是每次输出都不同。我做错了什么吗?谢谢
I'm trying to adopt RSA algorithm for encrypting String objects, but seems that BigInteger -> String and String -> BigInteger conversions do not work properly. Here's my code:
public class RSAEncryptor {
private BigInteger n, d, e;
public RSAEncryptor(int bitlen) {
SecureRandom r = new SecureRandom();
BigInteger p = new BigInteger(bitlen / 2, 100, r);
BigInteger q = new BigInteger(bitlen / 2, 100, r);
n = p.multiply(q);
BigInteger m = (p.subtract(BigInteger.ONE)).multiply(q.subtract(BigInteger.ONE));
e = new BigInteger("3");
while (m.gcd(e).intValue() > 1) {
e = e.add(new BigInteger("2"));
}
d = e.modInverse(m);
}
public String encrypt(String message) {
BigInteger plaintext = new BigInteger(message.getBytes());
return new String(plaintext.modPow(e, n).toByteArray());
}
public String decrypt(String message) {
BigInteger plaintext = new BigInteger(message.getBytes());
return new String(plaintext.modPow(d, n).toByteArray());
}
}
public class Main {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
RSAEncryptor encryptor = new RSAEncryptor(64);
String source = "1";
String crypted = encryptor.encrypt(source);
System.out.println(crypted);
String decrypted = encryptor.decrypt(crypted);
System.out.println(decrypted);
}
}
It prints not what is expected, and a strange thing is that every time the output differs. Am I doing something wrong? Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
加密消息是任意的
byte[]
,不保证能正确转换为特定字符编码的String
,所以不需要转换为>字符串。
另一个技巧是
plaintext
应该小于n
,否则算法会产生垃圾。当这个条件满足时,它对我来说就很好用。另一个可能的问题是,当消息的第一个字节大于或等于
0x80
时,将产生负的明文
。可以通过在将消息转换为 BigInteger 之前在消息字节前面添加一个零字节,并在逆转换期间剥离该字节来解决此问题。Encrypted message is an arbitrary
byte[]
, it's not guaranteed that it can be correctly converted toString
with particular character encoding, so there is no need to convert it toString
.Another trick is that
plaintext
should be less thann
, otherwise algorithm would produce garbage. When this condition is met, it works fine for me.Yet another possible problem is that when the first byte of message in greater or equal than
0x80
, a negativeplaintext
would be produced. It can be solved by prepending a zero byte to the bytes of message before converting it toBigInteger
, and stripping that byte during inverse conversion.提示: getBytes 与 message 的字符串值有何不同?
你为什么不直接做 BigInteger(message); ?
Hint: What does getBytes do that's different from the string value of message?
Why aren't you just doing BigInteger(message); ?