给定相同的明文和 public 密钥,是否可以生成 2 个相同的 RSA 密文?

Is it possible to generate 2 identical RSA ciphertext given the same plaintext and public key?

我在 Android 上玩 RSA,我意识到 RSA 加密在给定相同的明文和 public 密钥的情况下生成不同的密文,由于填充有没有办法生成给定相同明文和 public 密钥的相同密文?

同样,在给定相同的明文和私钥的情况下,运行之间的数字签名是否不同,有没有办法生成相同的数字签名?

这是我的注册机:

        KeyPairGenerator kpGenerator = KeyPairGenerator.getInstance("RSA", "AndroidKeyStore");
        AlgorithmParameterSpec spec = null;
        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN_MR1 && Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
            spec = new KeyPairGeneratorSpec.Builder(ctx)
                    .setAlias(mAlias)
                    .setSubject(new X500Principal("CN=" + mAlias))
                    .setSerialNumber(BigInteger.valueOf(1337))
                    .setStartDate(start.getTime())
                    .setEndDate(end.getTime())
                    .build();
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            spec = new KeyGenParameterSpec.Builder(mAlias,
                    KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
                    .setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA512)
                    .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1)
                    .build();
        kpGenerator.initialize(spec);
        KeyPair kp = kpGenerator.generateKeyPair();

以下是我的加密方式:

        KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
        keyStore.load(null);
        KeyStore.PrivateKeyEntry entry = (KeyStore.PrivateKeyEntry) keyStore.getEntry(mAlias, null);
        Cipher cip = null;

        RSAPublicKey pubKey = (RSAPublicKey)entry.getCertificate().getPublicKey();
        cip = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        cip.init(Cipher.ENCRYPT_MODE, pubKey);

        byte[] encryptBytes = cip.doFinal(challenge.getBytes());

谢谢。

要始终生成相同的密文,请使用无填充的算法。将 RSA/ECB/PKCS1Padding 替换为 RSA/ECB/NoPadding

但是,出于安全原因,我建议使用带填充的算法,如果可能的话,OAEP RSA/ECB/OAEPWithSHA-1AndMGF1Padding(可从 android 23 获得)。填充对于解密端应该不是问题

PCKS#1 数字签名将对相同的私钥和要签名的数据产生相同的结果