2017-03-02 315 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

相關問題