给定相同的明文和 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 数字签名将对相同的私钥和要签名的数据产生相同的结果
我在 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 数字签名将对相同的私钥和要签名的数据产生相同的结果