Java实现RSA加密解密无编译错误但无输出,求代码问题排查
代码问题汇总
- 问题1:私钥计算逻辑错误
代码注释明确要求私钥是公钥对(p-1)*(q-1)(即欧拉函数φ(n))求模逆,但实际代码里对modulus(也就是p*q)求逆,完全不符合RSA规则,且未校验公钥和φ(n)互素,会直接抛出ArithmeticException导致程序终止无输出。 - 问题2:BigInteger类型的解密方法逻辑错误
RSA解密规则是c^d mod n,原代码调用了modInverse求逆元,完全不是解密逻辑,无法还原明文。 - 问题3:字符串类型的加解密方法未实现RSA逻辑
原字符串加解密只是单纯做了Base64编解码,没有用到公钥、私钥做任何运算,完全不符合功能要求。 - 问题4:缺少φ(n)的全局变量存储
生成密钥对必须用到欧拉函数φ(n),需要提前计算存储。
修正后代码
package project4; import java.math.BigInteger; import java.util.Base64; import java.util.Random; public class PKC { BigInteger p, q, public_key, private_key, modulus, phi; Random rnd= new Random(); PKC() { p = BigInteger.probablePrime(1024, rnd); q = p.nextProbablePrime(); modulus = p.multiply(q); // 提前计算欧拉函数φ(n) phi = p.subtract(BigInteger.ONE).multiply(q.subtract(BigInteger.ONE)); } void genKeyPair() { public_key = BigInteger.probablePrime(20, rnd); // 校验公钥和φ(n)互素,不满足就重新生成公钥 while (phi.gcd(public_key).compareTo(BigInteger.ONE) != 0) { public_key = BigInteger.probablePrime(20, rnd); } // 私钥对φ(n)求模逆 private_key = public_key.modInverse(phi); } String encrypt(String m) { // 字符串转BigInteger走RSA加密,再转Base64输出 BigInteger mBig = new BigInteger(m.getBytes()); BigInteger cBig = encrypt(mBig); return Base64.getEncoder().encodeToString(cBig.toByteArray()); } String decrypt(String c) { // Base64解码转BigInteger走RSA解密,再转字符串 byte[] cBytes = Base64.getDecoder().decode(c); BigInteger cBig = new BigInteger(cBytes); BigInteger mBig = decrypt(cBig); return new String(mBig.toByteArray()); } BigInteger encrypt(BigInteger m) { return m.modPow(public_key, modulus); } BigInteger decrypt(BigInteger c) { // 解密用modPow,参数是私钥和模数 return c.modPow(private_key, modulus); } public static void main(String[] args) { PKC pkc = new PKC(); pkc.genKeyPair(); System.out.printf("p: %d\n\nq: %d\n\npublic key: %d\n\nprivate key: %d\n\nmodulus: %d\n\n", pkc.p, pkc.q, pkc.public_key, pkc.private_key, pkc.modulus); BigInteger m = new BigInteger("438709437431787"); BigInteger c = pkc.encrypt(m); System.out.printf("plaintext: %d\n\nciphertext: %d\n\ndecrypted text: %d\n\n", m, c, pkc.decrypt(c)); String plaintext = "test message"; String ciphertext = pkc.encrypt(plaintext); System.out.printf("plaintext: %s\n\nciphertext: %s\n\ndecrypted text: %s\n\n", plaintext, ciphertext, pkc.decrypt(ciphertext)); } }
内容的提问来源于stack exchange,提问作者foxtrotuniform
相关产品推荐
相关产品推荐

