Bu dokümanda, Android'in kriptografik özelliklerinin doğru şekilde kullanılması açıklanmakta ve bu özelliklerin kullanımına dair bazı örnekler verilmektedir. Uygulamanız için daha fazla anahtar güvenliği gerekiyorsa Android Anahtar Deposu sistemini kullanın.
Yalnızca Android Anahtar Deposu sistemiyle sağlayıcı belirtme
Android Anahtar Deposu sistemini kullanıyorsanız bir sağlayıcı belirtmeniz gerekir.
Ancak Android, belirli bir algoritma için belirli bir sağlayıcıyı garanti etmez. Android Anahtar Deposu sistemini kullanmadan bir sağlayıcı belirtmek, gelecekteki sürümlerde uyumluluk sorunlarına neden olabilir.
Önerilen bir algoritma seçin
Hangi algoritmayı kullanacağınızı seçme özgürlüğüne sahip olduğunuzda (ör. üçüncü taraf bir sistemle uyumluluğu gerektirmediğinizde) aşağıdaki algoritmaları kullanmanızı öneririz:
Sınıf | Öneri |
---|---|
Şifre | 256 bit anahtarlarla (AES/GCM/NoPadding gibi) CBC veya GCM modunda AES |
MessageDigest | SHA-2 ailesi (SHA-256 gibi) |
Mac | SHA-2 ailesi HMAC'si (HMACSHA256 gibi) |
İmza | ECDSA ile SHA-2 ailesi (SHA256withECDSA gibi) |
Genel şifreleme işlemlerini gerçekleştirme
Aşağıdaki bölümlerde, uygulamanızda yaygın kriptografik işlemleri nasıl tamamlayabileceğinizi gösteren snippet'ler bulunmaktadır.
İleti şifreleme
Kotlin
val plaintext: ByteArray = ... val keygen = KeyGenerator.getInstance("AES") keygen.init(256) val key: SecretKey = keygen.generateKey() val cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING") cipher.init(Cipher.ENCRYPT_MODE, key) val ciphertext: ByteArray = cipher.doFinal(plaintext) val iv: ByteArray = cipher.iv
Java
byte[] plaintext = ...; KeyGenerator keygen = KeyGenerator.getInstance("AES"); keygen.init(256); SecretKey key = keygen.generateKey(); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING"); cipher.init(Cipher.ENCRYPT_MODE, key); byte[] ciphertext = cipher.doFinal(plaintext); byte[] iv = cipher.getIV();
Mesaj özeti oluşturma
Kotlin
val message: ByteArray = ... val md = MessageDigest.getInstance("SHA-256") val digest: ByteArray = md.digest(message)
Java
byte[] message = ...; MessageDigest md = MessageDigest.getInstance("SHA-256"); byte[] digest = md.digest(message);
Dijital imza oluşturma
Çalışma zamanında oluşturabileceğiniz, uygulamanızla birlikte paketlenmiş bir dosyadan okuyabileceğiniz veya ihtiyaçlarınıza bağlı olarak başka bir kaynaktan alabileceğiniz imzalama anahtarını içeren bir PrivateKey
nesnenizin olması gerekir.
Kotlin
val message: ByteArray = ... val key: PrivateKey = ... val s = Signature.getInstance("SHA256withECDSA") .apply { initSign(key) update(message) } val signature: ByteArray = s.sign()
Java
byte[] message = ...; PrivateKey key = ...; Signature s = Signature.getInstance("SHA256withECDSA"); s.initSign(key); s.update(message); byte[] signature = s.sign();
Dijital imzaları doğrulama
İmzalayanın ortak anahtarını içeren bir PublicKey
nesnenizin olması gerekir. Bu nesneyi uygulamanızla birlikte paket halinde sunulan bir dosyadan okuyabilir, bir sertifikadan çıkarabilir veya ihtiyaçlarınıza bağlı olarak başka bir kaynaktan edinebilirsiniz.
Kotlin
val message: ByteArray = ... val signature: ByteArray = ... val key: PublicKey = ... val s = Signature.getInstance("SHA256withECDSA") .apply { initVerify(key) update(message) } val valid: Boolean = s.verify(signature)
Java
byte[] message = ...; byte[] signature = ...; PublicKey key = ...; Signature s = Signature.getInstance("SHA256withECDSA"); s.initVerify(key); s.update(message); boolean valid = s.verify(signature);
Uygulamanın karmaşıklığı
Android kriptografi uygulamasıyla ilgili, anormal görünen ancak uyumlulukla ilgili endişeler nedeniyle oluşan bazı ayrıntılar vardır. Bu bölümde, büyük olasılıkla karşılaşacağınız sorunlar ele alınmaktadır.
OAEP MGF1 mesaj özeti
RSA OAEP şifreleri iki farklı ileti özetiyle parametrelendirilir: "ana" özet ve MGF1 özeti. Ana özeti belirten ve MGF1 özetini belirtilmemiş durumda bırakan Cipher.getInstance("RSA/ECB/OAEPwithSHA-256andMGF1Padding")
gibi özet adlarını içeren Cipher
tanımlayıcılar vardır. Android Keystore'da MGF1 özeti için SHA-1 kullanılır. Diğer Android şifreleme sağlayıcıları için iki özet aynıdır.
Uygulamanızın kullandığı özetler üzerinde daha fazla kontrole sahip olmak için Cipher.getInstance("RSA/ECB/OAEPPadding")
'te olduğu gibi OAEPPadding ile şifre isteyin ve her iki özeti de açıkça seçmek için OAEPParameterSpec
ile init()
arasında bir değer sağlayın.
Bu durum aşağıdaki kodda gösterilmektedir:
Kotlin
val key: Key = ... val cipher = Cipher.getInstance("RSA/ECB/OAEPPadding") .apply { // To use SHA-256 the main digest and SHA-1 as the MGF1 digest init(Cipher.ENCRYPT_MODE, key, OAEPParameterSpec("SHA-256", "MGF1", MGF1ParameterSpec.SHA1, PSource.PSpecified.DEFAULT)) // To use SHA-256 for both digests init(Cipher.ENCRYPT_MODE, key, OAEPParameterSpec("SHA-256", "MGF1", MGF1ParameterSpec.SHA256, PSource.PSpecified.DEFAULT)) }
Java
Key key = ...; Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPPadding"); // To use SHA-256 the main digest and SHA-1 as the MGF1 digest cipher.init(Cipher.ENCRYPT_MODE, key, new OAEPParameterSpec("SHA-256", "MGF1", MGF1ParameterSpec.SHA1, PSource.PSpecified.DEFAULT)); // To use SHA-256 for both digests cipher.init(Cipher.ENCRYPT_MODE, key, new OAEPParameterSpec("SHA-256", "MGF1", MGF1ParameterSpec.SHA256, PSource.PSpecified.DEFAULT));
Desteği sonlandırılan işlevler
Aşağıdaki bölümlerde desteği sonlandırılan işlevler açıklanmaktadır. Uygulamanızda kullanmayın.
Bouncy Castle algoritmaları
Birçok algoritmanın Bouncy Castle uygulaması kullanımdan kaldırıldı. Bu durum yalnızca aşağıdaki örnekte gösterildiği gibi Bouncy Castle sağlayıcısını açıkça istediğiniz durumları etkiler:
Kotlin
Cipher.getInstance("AES/CBC/PKCS7PADDING", "BC") // OR Cipher.getInstance("AES/CBC/PKCS7PADDING", Security.getProvider("BC"))
Java
Cipher.getInstance("AES/CBC/PKCS7PADDING", "BC"); // OR Cipher.getInstance("AES/CBC/PKCS7PADDING", Security.getProvider("BC"));
Yalnızca Android Anahtar Deposu sistemiyle sağlayıcı belirtme ile ilgili bölümde belirtildiği gibi, belirli bir sağlayıcı talep etmek önerilmez. Bu kurala uyuyorsanız bu desteğin sonlandırılması sizi etkilemez.
Başlatma vektörü olmayan şifre tabanlı şifreleme anahtarları
Başlatma vektörü (IV) gerektiren şifre tabanlı şifreleme (PBE) şifreleri, uygun şekilde oluşturulmuşsa anahtardan veya açıkça iletilen bir IV'den bu vektörü alabilir. IV içermeyen bir PBE anahtarı ve açık bir IV iletmezseniz Android'deki PBE şifreleri şu anda sıfır IV olduğunu varsayar.
PBE şifreleri kullanırken her zaman aşağıdaki kod snippet'inde gösterildiği gibi açık bir IV iletin:
Kotlin
val key: SecretKey = ... val cipher = Cipher.getInstance("PBEWITHSHA256AND256BITAES-CBC-BC") val iv = ByteArray(16) SecureRandom().nextBytes(iv) cipher.init(Cipher.ENCRYPT_MODE, key, IvParameterSpec(iv))
Java
SecretKey key = ...; Cipher cipher = Cipher.getInstance("PBEWITHSHA256AND256BITAES-CBC-BC"); byte[] iv = new byte[16]; new SecureRandom().nextBytes(iv); cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(iv));
Kripto para sağlayıcı
Android 9 (API düzeyi 28) itibarıyla Crypto Java Cryptography Architecture (JCA) sağlayıcısı kaldırıldı. Uygulamanız, şifreleme sağlayıcısının bir örneğini isterse (ör. aşağıdaki yöntemi çağırarak) NoSuchProviderException
gerçekleşir.
Kotlin
SecureRandom.getInstance("SHA1PRNG", "Crypto")
Java
SecureRandom.getInstance("SHA1PRNG", "Crypto");
Jetpack Security şifreleme kitaplığı
Jetpack güvenlik şifreleme kitaplığı desteği sonlandırıldı. Bu durum yalnızca uygulama modülünüzün build.gradle
dosyasında aşağıdaki bağımlılıklara sahip olduğunuz durumları etkiler:
Eski
dependencies { implementation "androidx.security:security-crypto:1.0.0" }
Kotlin
dependencies { implementation("androidx.security:security-crypto:1.0.0") }
Desteklenen algoritmalar
Android'de desteklenen JCA algoritma tanımlayıcıları şunlardır:
AlgorithmParameterGenerator
AlgorithmParameters
CertPathBuilder
CertPathValidator
CertStore
CertificateFactory
Cipher
KeyAgreement
KeyFactory
KeyGenerator
KeyManagerFactory
KeyPairGenerator
KeyStore
Mac
MessageDigest
SSLContext
SSLEngine.Supported
SSLSocket.Supported
SecretKeyFactory
SecureRandom
Signature
TrustManagerFactory