Java RSA/ECB/NOP添加解密返回空字符

Java RSA/ECB/NOP添加解密返回空字符,java,rsa,Java,Rsa,我使用RSA算法加密字符串,加密和解密逻辑是 public class RsaEncrypt { private static final String ALGORITHM = "RSA"; public static void main(String[] args) { String filePath = "/home/Desktop/abc.jks"; char[] password = "changeit".toCharArray(); String alias

我使用RSA算法加密字符串,加密和解密逻辑是

public class RsaEncrypt {

private static final String ALGORITHM = "RSA";

public static void main(String[] args) {
    String filePath = "/home/Desktop/abc.jks";
    char[] password = "changeit".toCharArray();
    String alias = "123";
    KeyStore ks = null;

    try {

        //loading the keystore
        ks = KeyStore.getInstance("JKS");
        InputStream readStream = new FileInputStream(filePath);
        ks.load(readStream, password);
        Certificate cert = ks.getCertificate(alias);

        PublicKey publicKey = cert.getPublicKey();
        PrivateKey privateKey = (PrivateKey) ks.getKey(alias, password);

        RsaEncrypt e = new RsaEncrypt();
        String result = e.encrypt("abvhdh", publicKey);
        String decryptResult = e.decrypt(result.getBytes(), privateKey);

    } catch (Exception e) {
        e.printStackTrace();
    }
}


//Encryption of a string

public String encrypt(String text,PublicKey publicKey) {

    String retVal = null;
    byte[] cipherText = null;

    try {

        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
         cipherText = cipher.doFinal(text.getBytes());

        cipherText = Base64.getEncoder().encode(cipherText);

    } catch (Exception e) {
        e.printStackTrace();
        throw new RuntimeException(e);

    }
    return new String(cipherText) ;
}




// Decryption of a string
    private String decrypt(byte[] text, PrivateKey privatekey) {
        byte[] dectyptedText = null;

        try {
            final Cipher cipher = Cipher.getInstance(ALGORITHM);
            cipher.init(Cipher.DECRYPT_MODE, privatekey);
            dectyptedText = cipher.doFinal(Base64.getDecoder().decode(text));

            } catch (Exception ex) {
            ex.printStackTrace();
        } catch (Throwable e) {
            throw new RuntimeException(e);
        }
        return new String(dectyptedText);
    }
结果很好,但是如果我再次加密同一个字符串,我会得到不同的加密值

为此,我使用RSA/ECB/NOP添加密码而不是RSA,然后如果我多次加密一个字符串,我将得到相同的加密值。 但是当我解密时,reuslt字符串包含一些空字符

范例 输入:abcd输出:abcd\u0000\u0000\u0000\u0000

如何解决这个问题?如果我们多次加密,获得相同加密值的最佳方法是什么

结果很好,但是如果我再次加密同一个字符串,我会得到不同的加密值

这是正确的,它甚至是RSA加密的必需属性。默认情况下,PKCS1.5填充使用RSA/ECB/PKCS1Padding,其中包含一些随机字节。更安全的选择是RSA/ECB/OAEPWITHHA-256和MGF1PADDING模式,这种模式更随机

为此,我使用RSA/ECB/NOP添加密码而不是RSA,然后如果我多次加密一个字符串,我将得到相同的加密值。但是当我解密时,reuslt字符串包含一些空字符

使用RSA而不添加填充是非常不安全的

填充将原始加密值扩展到整个空间长度,例如2048位,然后将执行RSA幻方幂运算。使用NoPadding参数可以告诉加密库您将自己进行填充。在这种情况下,您需要在解密后删除填充,在您的情况下为零填充

我希望你这样做是为了学习/学术目的,而不是真正的安全项目。你可以看看我的文章,以得到一些例子


顺便说一句:您不应该使用RSA加密明文本身。而是使用对称加密加密明文,然后使用RSA加密对称加密密钥

谢谢你的休息。。有没有办法使用RSA算法获得相同的加密值???@anth为什么需要相同的值?一种选择是使用自己的静态填充(如NoPadding),但这会降低解决方案的安全性。随机填充是RSA安全的必要条件。错误实现的填充甚至可能泄露您的私钥。实际上,我正在为一个数字生成一个随机值,并将随机值和numberCrypted值存储在数据库中。若尝试为已经存在的加密值生成随机值,那个么我将得到异常。我需要检查数据库中是否存在加密值。要检查这种情况,我需要多次获得相同的值encryption@anth这不是rsa加密的目的。如果要比较值,哈希或hmac可能更适合您。