使用RSA从模和指数生成密钥的Java加密/解密

使用RSA从模和指数生成密钥的Java加密/解密,java,security,encryption,rsa,Java,Security,Encryption,Rsa,我试图从模、公共指数和私有指数生成一对密钥,对字符串进行加密,然后对其进行解密,但解密后的输出与输入不同 public class EncryptDecrypt { public void encryptDecriptKey(){ String text = new String("Hello"); byte[] cipherData = null; byte[] cipherData2 = null; BigInteger modulus = new BigIn

我试图从模、公共指数和私有指数生成一对密钥,对字符串进行加密,然后对其进行解密,但解密后的输出与输入不同

public class EncryptDecrypt {
public void encryptDecriptKey(){
    String text = new String("Hello");
    byte[] cipherData = null;
    byte[] cipherData2 = null;
    BigInteger modulus = new BigInteger("E265721199CB82C4080E6E4B87368D01701A1171704629C66BA67DFF1127BB287F9494C8FE80D95D591FEE57D90D96359309AC650E7D0DF39FAAE366C5D5D89F58B4C21FDA80A2792700196FF5AF2635D89DAAF5E622FB84059DE0A4F23DC5F2895917879FC72AA7AF587361D7D3E8578B17BAA92E26D8637D9F8F7556B8FAC1E7A72AB6462EE192CC2ABE81A1E50FEAF9D2967F4DB92DDCA617272ED21A685B8896A9A2D34B24E723693865022B7776D134A041FA7ADFB1BB7B53C7AD891BB3A28E1AE7B399AB3CAC10E55432159A513FB24847129926A344C92DC984F002A97895373B353186E30A9CB33CA3DC7617A4FCBC0BAA1CCBF1E22286F1A9A09D89", 16);
    BigInteger pubExp = new BigInteger("65537", 16);
    BigInteger privateExp = new BigInteger("6274C5AFBBD7926DD8271676483E44022D135924A1341234D55A198F549197C61BFDACDAE03B7ECC26D7491AF12D04771613EDE220F3E79E5C80BFD6511117DCEC81E7AE5CA2F685839D7A728341017807554225204974624CE304F016DD2079C29B792D2522437D9B36F72EC4E2C637542924A73087FA31024FE2DE9FB1607323B8F98020FF0EEFE386DFEB77931C0146B60F757A30397955CF554D86654DD5E9AD600E7982FD59B052DB1014BC186ABE0E0D7250EBDD6BB789DC29DEA9ADCFD12D5713CFAC53FB28035C7F436EEE3519C13DC6516AAA549B07E190F6D4754ED4CF4953EE1773E6E091E93D3C34668FFFC6AA2230A8367DEA9BC348F335B925", 16);

    KeyFactory keyFactory = null;
    RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(modulus, pubExp);
    RSAPublicKey key = null;
    Cipher cipher = null;
    try {
        keyFactory = KeyFactory.getInstance("RSA");
        key = (RSAPublicKey) keyFactory.generatePublic(pubKeySpec);
        cipher = Cipher.getInstance("RSA/ECB/NoPadding");
        cipher.init(Cipher.ENCRYPT_MODE, key);
        cipherData = cipher.doFinal(text.getBytes());
    } catch (IllegalBlockSizeException | BadPaddingException | InvalidKeyException | NoSuchPaddingException | NoSuchAlgorithmException | InvalidKeySpecException e) {
        e.printStackTrace();
    }



    KeyFactory keyFactory2 = null;
    RSAPrivateKeySpec privateKeySpec = new RSAPrivateKeySpec(modulus, privateExp);
    RSAPrivateKey privatekey = null;
    Cipher cipher2 = null;
    try {
        keyFactory2 = KeyFactory.getInstance("RSA");
        privatekey = (RSAPrivateKey) keyFactory1.generatePrivate(privateKeySpec);
        cipher2 = Cipher.getInstance("RSA/ECB/NoPadding");
        cipher2.init(Cipher.DECRYPT_MODE, privatekey);
        cipherData2 = cipher2.doFinal(cipherData);
    } catch (IllegalBlockSizeException | BadPaddingException | InvalidKeyException | NoSuchPaddingException | NoSuchAlgorithmException | InvalidKeySpecException e) {
        e.printStackTrace();
    }

        System.out.println(Arrays.toString(text.getBytes()));
        System.out.println(Arrays.toString(cipherData2));
        //the two outputs should be equals
}

}这是因为当指数以10为基数时,指数以16为基数

BigInteger pubExp = new BigInteger("65537", 16);
这应该是:

BigInteger pubExp = new BigInteger("65537", 10);


此外,在这个修复之后,结果通常用零字节填充。在比较字符串之前,需要删除这些值

原因是RSA是对数字进行操作的。由于未使用填充方法,因此无法删除此填充:原始纯文本也可能以零值字节开始。因此,您可以将明文填充到大小的模数(即密钥大小)


要修复最后一部分,请使用安全填充,例如OAEP填充:
“RSA/ECB/OAEPwithsha1和mgf1填充”
进行加密和解密。

原始RSA-由
“NoPadding”
表示不安全。请注意,原始RSA使用模幂运算。这意味着,任何大于模数的值首先会减少到[0,N]范围内的值,其中N是模数。当转换为字符串时,这很可能看起来像垃圾。没有输入、输出和(测试)我们无法调试关键值。请尝试创建一个MCVE。@MaartenBodewes现在它是一个MCVerrelated:我复制粘贴忘记更改指数谢谢!很好,Devon;alexius,我无法从你的评论中判断这是否解决了你的问题。Devon,我有另一个问题要补充,希望你不介意我将它添加到你的答案中;两者都是问题,不是他们将一起解决这个问题。@MaartenBodewes谢谢,我真的想知道在你的演讲结束后最好的解决方案是什么comment@alexsius如果这解决了你的问题,你可能会找到答案。
BigInteger pubExp = BigInteger.valueOf(65537);