Kriptografi

Bu belgede, Android'in kriptografik olanaklarının doğru şekilde nasıl kullanılacağı açıklanmakta ve bu olanakların kullanımına ilişkin bazı örnekler verilmektedir. Uygulamanız daha fazla anahtar güvenliği gerektiriyorsa 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 diğer durumlarda Android, belirli bir algoritma için belirli bir sağlayıcıyı garanti etmez. Android Keystore sistemini kullanmadan sağlayıcı belirtmek, gelecekteki sürümlerde uyumluluk sorunlarına neden olabilir.

Önerilen bir algoritma seçme

Hangi algoritmayı kullanacağınızı seçme özgürlüğünüz olduğunda (ör. üçüncü taraf bir sistemle uyumluluk gerekmediğinde) aşağıdaki algoritmaları kullanmanızı öneririz:

Sınıf Öneri
Cipher 256 bit anahtarlarla CBC veya GCM modunda AES (ör. AES/GCM/NoPadding)
MessageDigest SHA-2 ailesi (ör. SHA-256)
Mac SHA-2 ailesi HMAC'si (ör. HMACSHA256)
İmza ECDSA ile SHA-2 ailesi (ör. SHA256withECDSA)

Yaygın kriptografik işlemleri gerçekleştirme

Aşağıdaki bölümlerde, uygulamanızda yaygın kriptografik işlemleri nasıl tamamlayabileceğinizi gösteren kod snippet'leri yer almaktadır.

İletileri ş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

İmzalama anahtarını içeren bir PrivateKey nesneniz olmalıdır. Bu nesneyi çalışma zamanında oluşturabilir, uygulamanızla birlikte paketlenmiş bir dosyadan okuyabilir veya ihtiyaçlarınıza bağlı olarak başka bir kaynaktan alabilirsiniz.

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 imzayı doğrulama

İmzalayanın ortak anahtarını içeren bir PublicKey nesneniz olmalıdır. Bu nesneyi uygulamanızla birlikte paketlenmiş bir dosyadan okuyabilir, sertifikadan çıkarabilir veya ihtiyaçlarınıza bağlı olarak başka bir kaynaktan alabilirsiniz.

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

Uygulama karmaşıklıkları

Android kriptografi uygulamasında, alışılmadık gibi görünen ancak uyumluluk sorunları nedeniyle mevcut olan bazı ayrıntılar vardır. Bu bölümde, en sık 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. Cipher karma adları içeren tanımlayıcılar vardır. Örneğin, Cipher.getInstance("RSA/ECB/OAEPwithSHA-256andMGF1Padding"), ana karmayı belirtir ve MGF1 karmasını belirtilmemiş olarak bırakır. Android Keystore için MGF1 özetinde SHA-1 kullanılırken diğer Android şifreleme sağlayıcılarında iki özet aynıdır.

Uygulamanızın kullandığı özetler üzerinde daha fazla kontrol sahibi olmak için Cipher.getInstance("RSA/ECB/OAEPPadding") örneğindeki gibi OAEPPadding ile bir şifre isteyin ve her iki özeti de açıkça seçmek için init()'ye OAEPParameterSpec 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));

Kullanımdan kaldı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 uygulamaları kullanımdan kaldırılmıştır. 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 hakkındaki bölümde belirtildiği gibi, belirli bir sağlayıcıyı istemeniz önerilmez. Bu yönergeye uyarsanız bu kullanımdan kaldırma işleminden etkilenmezsiniz.

Başlatma vektörü olmayan şifre tabanlı şifreleme şifreleri

Başlatma vektörü (IV) gerektiren parola tabanlı şifreleme (PBE) şifreleri, uygun şekilde oluşturulmuşsa anahtardan veya açıkça iletilen bir IV'den başlatma vektörü alabilir. IV içermeyen bir PBE anahtarı iletirseniz ve açık bir IV iletmezseniz Android'deki PBE şifreleri şu anda sıfır IV'yi 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'dan (API düzeyi 28) itibaren Crypto Java Cryptography Architecture (JCA) sağlayıcısı kaldırıldı. Uygulamanız aşağıdaki yöntemi çağırarak Crypto sağlayıcısının bir örneğini isterse NoSuchProviderException oluşur.

Kotlin

SecureRandom.getInstance("SHA1PRNG", "Crypto")

Java

SecureRandom.getInstance("SHA1PRNG", "Crypto");

Jetpack security-crypto kitaplığı

security-crypto Jetpack kitaplığındaki tüm API'lerin desteği, sürüm 1.1.0'ün kararlı sürümünde sonlandırıldı. Bu kitaplığın sonraki sürümleri yayınlanmayacak.

Uygulama modülünüzün build.gradle dosyasında aşağıdaki bağımlılıklardan herhangi biri varsa kullanımdan kaldırma ek açıklamaları görünür:

Groovy

dependencies {
    implementation "androidx.security:security-crypto:1.1.0"
    // or
    implementation "androidx.security:security-crypto-ktx:1.1.0"
}

Kotlin

dependencies {
    implementation("androidx.security:security-crypto:1.1.0")
    // or
    implementation("androidx.security:security-crypto-ktx:1.1.0")
}

Desteklenen algoritmalar

Android'de desteklenen JCA algoritma tanımlayıcıları şunlardır: