2017-03-02 308 views
0

我在Android上玩弄RSA,并且我意识到由于填充,给定相同的明文和公钥,RSA加密会生成不同的密文有没有办法在给定相同的明文和公钥的情况下生成相同的密文?给定相同的明文和公钥可能生成2个相同的RSA密文吗?

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

这里是我的凯基:

 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()); 

感谢。

+0

你能告诉我们你是如何加密问题

一个PCKS#1数字签名将产生相同的结果为相同的私钥和数据签名? RSA算法*本身是确定性的,所以给定完全相同的明文和公钥,加密输出不应该不同。如果您使用Java的[Cipher](http://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html#Cipher),则某些模式(例如CBC)将以如果没有特别指定,则为随机IV。 – ephemient

+0

是的,你可以申请一个没有填充的密码字符串。但你为什么要这么做? –

+0

我如何请求一个没有填充的密码字符串? – user1118764

回答

1

要生成总是相同的密文,请使用不带填充的算法。将RSA/ECB/PKCS1Padding替换为RSA/ECB/NoPadding

但是,出于安全原因,我建议使用带有填充的算法,并且如果可能的话,OAEP RSA/ECB/OAEPWithSHA-1AndMGF1Padding(它可从android 23获得)。填充不应当成为解密侧

+0

谢谢!这工作。你会碰巧知道密钥材料是否只能通过创建过程/应用程序访问?此外,密钥材料是否持久(在软件KeyStore和硬件支持的KeyStore中)?那么,我的意思是,在创建应用程序卸载并且出厂重置后,KeyStore中的密钥是否会被删除? – user1118764

+0

关键材料只能由创建它的应用程序访问(但不能提取)。硬件支持取决于设备,如果有可用的话(有api方法来检查是否存在)。如果您卸载应用程序或重置设备,则不再可以访问这些密钥。 – pedrofb

+0

谢谢。根植设备怎么样?在这种情况下,其他应用程序或root用户是否可以访问密钥材料?此外,工厂重置是否真的消除了硬件支持的关键材料(驻留在TEE中)? – user1118764

相关问题