Java 为什么我的RSA加密代码适用于较小的位,而不是较大的位?
我不需要编写太多代码,但是当我尝试在JAVA中实现RSA加密时,我的加密和解密可以用于较小的素数,但是当我尝试用于1536位素数时,解密就停止了。我已经经历过了,但我不知道问题出在哪里 我已经试着看看在什么时候,比特长度开始成为一个问题,当我将它设置为50时,它似乎停止工作。如果我的mod inverse方法抛出一个关于e.modinv(lambda)的错误,我也倾向于得到一个错误 不可能。我试图通过添加do循环来解决这个问题,但似乎这并没有解决这个问题Java 为什么我的RSA加密代码适用于较小的位,而不是较大的位?,java,encryption,rsa,Java,Encryption,Rsa,我不需要编写太多代码,但是当我尝试在JAVA中实现RSA加密时,我的加密和解密可以用于较小的素数,但是当我尝试用于1536位素数时,解密就停止了。我已经经历过了,但我不知道问题出在哪里 我已经试着看看在什么时候,比特长度开始成为一个问题,当我将它设置为50时,它似乎停止工作。如果我的mod inverse方法抛出一个关于e.modinv(lambda)的错误,我也倾向于得到一个错误 不可能。我试图通过添加do循环来解决这个问题,但似乎这并没有解决这个问题 public BigInteger Ra
public BigInteger Random_Prime()
{
SecureRandom random = new SecureRandom();
byte [] randomize = new byte [192];
random.nextBytes(randomize);
BigInteger big = new BigInteger(randomize);
return big.probablePrime(1536,random);
}
public BigInteger lcm(BigInteger p, BigInteger q)
{
long p1 = p.longValue()-1;
long q1 = q.longValue()-1;
BigInteger test1 = p.valueOf(p1);
BigInteger test2 = p.valueOf(q1);
return test1.multiply(test2).divide(test1.gcd(test2));
做{
我希望75在经过加密和解密后会变成75。您的lcm()
是错误的。
Javalong
只有64位(包括符号),不能表示大于2^63的数字。(或等于2^63,但大素数永远不等于2的幂。)因此,您的lcm
计算应该适用于p,q高达63位的情况,对我也适用,但对任何较大的数字都会产生完全错误和无用的结果。请使用{p,q}.subtract(BigInteger.ONE)
用于乘以gcd并除以的数字
另外,biginger.probablePrime(int,Random)
是一个静态方法(又称类范围方法);您不需要使用任何实例调用它,更不用说使用随机值的方法了,因为它被忽略了,所以您浪费了计算时间。因此biginger.valueOf(long)
也是静态的
并忽略用于调用它的任何实例。如果您使用的Java开发环境比简单地在shell或命令中键入javac
更高级,那么它应该(至少可以选择)向您发出关于使用实例调用静态方法的警告
最后,如果您不知道,直接使用RSA原语m^e mod n和c^d mod n加密/解密数据(尤其是小数据)是不安全的。您必须使用足够大和随机的填充方案才能确保安全;请参阅以获取简短的解释,以及是否需要更多搜索,以及可能需要搜索的位置如果你仅仅通过c.modPow(d,n)
进行解密(你没有展示),那么这既低效(参见维基百科关于CRT的内容),又不安全(参见维基百科关于定时攻击的内容,再次提及crypto.SX和security.SX)。而直接将RSA用于数据是非常有限和低效的,因此在实践中,人们使用混合加密——使用对称算法(现在通常是AES)对nonce密钥下的数据进行加密,并使用RSA对该nonce密钥进行加密——或者更好地使用RSA-KEM派生它(再次参见wikipedia crypto.SX security.SX)
如果您真的想要安全性而不仅仅是玩游戏,请使用Java库中正确实现(并经过审查)的加密由有能力的人编写,不像您的代码。您获得JCE扩展了吗?我不太会编写代码,也不知道那是什么。这是一项针对class@ElliottFrisch:Oracle Java在2017年默认情况下停止执行旧的基于ITAR的策略(OpenJDK从一开始就没有这样做),甚至在此之前,它只适用于JCE提供程序中的对称算法(主要是AES),而不适用于RSA,当然也不适用于您自己编写的代码。
p = obj1.Random_Prime();
q = obj1.Random_Prime();
lambda = obj1.lcm(p, q);
}
while(lambda.gcd(e).compareTo(ONE)!=0);
BigInteger n = p.multiply(q);
BigInteger m = new BigInteger("75");
BigInteger d = e.modInverse(lambda);
BigInteger c = obj1.Encrypt(n,e,m);