2015-11-17 17 views
23

tôi đang cố gắng để mã hóa và giải mã tên trong ứng dụng sử dụng KeyStore,Mã hóa và giải mã tên người dùng bằng KeyStore trong Android M và phiên bản cũ hơn?

Sử dụng KeyPairGeneratorSpec để tạo ra chìa khóa trong phiên bản cũ hơn như 18-22,

KeyPairGeneratorSpec như được depricated trong phiên bản 23 của android M, Nhưng Android M hỗ trợ KeyGenParameterSpec.

KeyGenParameterSpec này có hỗ trợ tính tương thích ngược hay không?

Tôi đang thử một số điều như thế này, có giải pháp nào tốt hơn cho việc này không. Tính năng này hoạt động tốt ngay bây giờ!

Tại thời điểm Ciper.getInstance mã hóa và Giải mã, tôi cần thực hiện việc này. có tham số đơn "RSA/ECB/OAEPWithSHA-256AndMGF1Padding" hoặc "RSA/ECB/PKCS1Padding" nào tôi có thể chuyển cho cả phiên bản không?

if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M){ 
      c = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding"); 
     }else{ 
      c = Cipher.getInstance("RSA/ECB/PKCS1Padding"); 
     } 

Dưới đây mã hoạt động tốt như bây giờ, hãy cho tôi biết cách cải thiện điều này.

Key Generator:

genkey(){ 
KeyPairGenerator generator = KeyPairGenerator .getInstance(KeyProperties.KEY_ALGORITHM_RSA, "AndroidKeyStore"); 
      if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M){ 
       TCLog.e(TAG,"Current version is 23(MashMello)"); 
       //Api level 23 

       KeyGenParameterSpec spec = new KeyGenParameterSpec.Builder(
          keyName, 
          KeyProperties.PURPOSE_DECRYPT | KeyProperties.PURPOSE_ENCRYPT) 
          .setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA512) 
          .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_OAEP) 
          .build(); 
       generator.initialize(spec); 
      }else{ 
       TCLog.e(TAG,"Current version is < 23(MashMello)"); 
       //api level 17+ 4.4.3 
       KeyPairGeneratorSpec spec = new KeyPairGeneratorSpec.Builder(getActivity()) 
         .setAlias(keyName) 
         .setSubject(new X500Principal("CN=Sample Name, O=Android Authority")) 
         .setSerialNumber(BigInteger.ONE) 
         .setStartDate(start.getTime()) 
         .setEndDate(end.getTime()) 
         .build(); 
       generator.initialize(spec); 
      } 
      KeyPair keyPair = generator.generateKeyPair(); 
} 

Encryption mã:

doEncription(){ 
try { 
     KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry) ks.getEntry(keyName, null); 
     PublicKey publicKey = (PublicKey) privateKeyEntry.getCertificate().getPublicKey(); 
     Cipher c; 
     if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M){ 
      c = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding"); 
     }else{ 
      c = Cipher.getInstance("RSA/ECB/PKCS1Padding"); 
     } 

     c.init(Cipher.ENCRYPT_MODE, publicKey); 
     encodedUser = c.doFinal(userName.getBytes()); 
     encodedPassword = c.doFinal(userPassword.getBytes()); 

     userName = Base64.encodeToString(encodedUser, Base64.DEFAULT); 
     userPassword = Base64.encodeToString(encodedPassword, Base64.DEFAULT); 
     // Log.e("MainActivity","AES Encription Error.!"); 
    } catch (Exception e) { 
     Log.e("MainActivity", "AES Encription Error.!"); 
    } 
} 

Giải mã Mã số:

doDecryption(){ 
    try { 
     KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry) ks.getEntry(keyName, null); 
     PrivateKey privateKey = (PrivateKey) privateKeyEntry.getPrivateKey(); 

     Cipher c; 
     if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M){ 
      c = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding"); 
     }else{ 
      c = Cipher.getInstance("RSA/ECB/PKCS1Padding"); 
     } 
     c.init(Cipher.DECRYPT_MODE, privateKey); 
     decodedUser = c.doFinal(encodedUser); 
     decodedPassword = c.doFinal(encodedPassword); 

    } catch (Exception e) { 
     Log.e("MainActivity", "AES Decryption Error.!"); 
    } 

} 
+0

@ nikolay-elenkov bạn có thể xem nhanh mã này không? có an toàn để mã hóa dữ liệu nhạy cảm không? – deviant

+1

bạn có thể cho tôi biết một liên kết nơi tôi có thể tìm thấy mã đầy đủ hoặc nơi bạn lấy mã không? –

Trả lời

3

việc chuyển đổi cypher phụ thuộc vào những gì thông số bạn cung cấp cho KeyGenParameterSpec hoặc KeyPairGeneratorSpec. Nếu bạn muốn sử dụng "RSA/ECB/PKCS1Padding" trong cả hai trường hợp (Android M và dưới) thay đổi

spec.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_OAEP) 

để

spec.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1) 

Bạn có thể kiểm tra các thuật toán có sẵn với các đoạn mã sau:

Provider[] providers = Security.getProviders(); 
    for (Provider p : providers) { 
     Log.d(TAG, "provider: " + p.getName()); 
     Set<Provider.Service> services = p.getServices(); 
     for (Provider.Service s : services) { 
      Log.d(TAG, "--> algorithm: " + s.getAlgorithm()); 
     } 
    } 

Tôi tránh viết rất nhiều if-else bằng cách khai báo một giao diện IKeyStoreHandler cung cấp tất cả các phương thức cần thiết (thêm/xóa khóa, liệt kê tất cả bằng các bí danh của họ, nhận khóa riêng/khóa công khai, giải mã/mã hóa văn bản) và triển khai nó cho cả hai trường hợp.

Các vấn đề liên quan