Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/368.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么我的RSA加密代码适用于较小的位,而不是较大的位?_Java_Encryption_Rsa - Fatal编程技术网

Java 为什么我的RSA加密代码适用于较小的位,而不是较大的位?

Java 为什么我的RSA加密代码适用于较小的位,而不是较大的位?,java,encryption,rsa,Java,Encryption,Rsa,我不需要编写太多代码,但是当我尝试在JAVA中实现RSA加密时,我的加密和解密可以用于较小的素数,但是当我尝试用于1536位素数时,解密就停止了。我已经经历过了,但我不知道问题出在哪里 我已经试着看看在什么时候,比特长度开始成为一个问题,当我将它设置为50时,它似乎停止工作。如果我的mod inverse方法抛出一个关于e.modinv(lambda)的错误,我也倾向于得到一个错误 不可能。我试图通过添加do循环来解决这个问题,但似乎这并没有解决这个问题 public BigInteger Ra

我不需要编写太多代码,但是当我尝试在JAVA中实现RSA加密时,我的加密和解密可以用于较小的素数,但是当我尝试用于1536位素数时,解密就停止了。我已经经历过了,但我不知道问题出在哪里

我已经试着看看在什么时候,比特长度开始成为一个问题,当我将它设置为50时,它似乎停止工作。如果我的mod inverse方法抛出一个关于e.modinv(lambda)的错误,我也倾向于得到一个错误 不可能。我试图通过添加do循环来解决这个问题,但似乎这并没有解决这个问题

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()
是错误的。

Java
long
只有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);