मैं यह सवाल क्यों पूछता हूं:
मुझे पता है कि एईएस एन्क्रिप्शन के बारे में बहुत सारे सवाल हैं, यहां तक कि एंड्रॉइड के लिए भी। और अगर आप वेब सर्च करते हैं तो बहुत सारे कोड स्निपेट हैं। लेकिन हर एक पेज पर, हर स्टैक ओवरफ्लो प्रश्न में, मुझे बड़े अंतर के साथ एक और कार्यान्वयन मिलता है।
इसलिए मैंने "सर्वश्रेष्ठ अभ्यास" खोजने के लिए यह प्रश्न बनाया। मुझे उम्मीद है कि हम सबसे महत्वपूर्ण आवश्यकताओं की एक सूची एकत्र कर सकते हैं और एक कार्यान्वयन स्थापित कर सकते हैं जो वास्तव में सुरक्षित है!
मैं आरंभीकरण वैक्टर और लवण के बारे में पढ़ता हूं। सभी कार्यान्वयन मुझे नहीं मिले, जिनमें ये विशेषताएं थीं। तो क्या आपको इसकी आवश्यकता है? क्या यह सुरक्षा को बहुत बढ़ाता है? आप इसे कैसे लागू करते हैं? यदि एन्क्रिप्ट किया गया डेटा डिक्रिप्ट नहीं किया जा सकता है तो एल्गोरिथ्म को अपवादों को उठाना चाहिए? या कि असुरक्षित है और यह सिर्फ एक अपठनीय स्ट्रिंग लौटना चाहिए? क्या एल्गोरिथ्म SHA के बजाय Bcrypt का उपयोग कर सकता है?
इन दो कार्यान्वयनों के बारे में मुझे क्या मिला? क्या वे ठीक हैं? बिल्कुल सही या कुछ महत्वपूर्ण बातें याद आ रही हैं? इनमें से क्या सुरक्षित है?
एल्गोरिथ्म को एन्क्रिप्शन के लिए एक स्ट्रिंग और एक "पासवर्ड" लेना चाहिए और फिर उस पासवर्ड के साथ स्ट्रिंग को एन्क्रिप्ट करना चाहिए। आउटपुट फिर से एक स्ट्रिंग (हेक्स या बेस 64?) होना चाहिए। निश्चित रूप से डिक्रिप्शन भी संभव होना चाहिए।
Android के लिए सही AES कार्यान्वयन क्या है?
कार्यान्वयन # 1:
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
public class AdvancedCrypto implements ICrypto {
public static final String PROVIDER = "BC";
public static final int SALT_LENGTH = 20;
public static final int IV_LENGTH = 16;
public static final int PBE_ITERATION_COUNT = 100;
private static final String RANDOM_ALGORITHM = "SHA1PRNG";
private static final String HASH_ALGORITHM = "SHA-512";
private static final String PBE_ALGORITHM = "PBEWithSHA256And256BitAES-CBC-BC";
private static final String CIPHER_ALGORITHM = "AES/CBC/PKCS5Padding";
private static final String SECRET_KEY_ALGORITHM = "AES";
public String encrypt(SecretKey secret, String cleartext) throws CryptoException {
try {
byte[] iv = generateIv();
String ivHex = HexEncoder.toHex(iv);
IvParameterSpec ivspec = new IvParameterSpec(iv);
Cipher encryptionCipher = Cipher.getInstance(CIPHER_ALGORITHM, PROVIDER);
encryptionCipher.init(Cipher.ENCRYPT_MODE, secret, ivspec);
byte[] encryptedText = encryptionCipher.doFinal(cleartext.getBytes("UTF-8"));
String encryptedHex = HexEncoder.toHex(encryptedText);
return ivHex + encryptedHex;
} catch (Exception e) {
throw new CryptoException("Unable to encrypt", e);
}
}
public String decrypt(SecretKey secret, String encrypted) throws CryptoException {
try {
Cipher decryptionCipher = Cipher.getInstance(CIPHER_ALGORITHM, PROVIDER);
String ivHex = encrypted.substring(0, IV_LENGTH * 2);
String encryptedHex = encrypted.substring(IV_LENGTH * 2);
IvParameterSpec ivspec = new IvParameterSpec(HexEncoder.toByte(ivHex));
decryptionCipher.init(Cipher.DECRYPT_MODE, secret, ivspec);
byte[] decryptedText = decryptionCipher.doFinal(HexEncoder.toByte(encryptedHex));
String decrypted = new String(decryptedText, "UTF-8");
return decrypted;
} catch (Exception e) {
throw new CryptoException("Unable to decrypt", e);
}
}
public SecretKey getSecretKey(String password, String salt) throws CryptoException {
try {
PBEKeySpec pbeKeySpec = new PBEKeySpec(password.toCharArray(), HexEncoder.toByte(salt), PBE_ITERATION_COUNT, 256);
SecretKeyFactory factory = SecretKeyFactory.getInstance(PBE_ALGORITHM, PROVIDER);
SecretKey tmp = factory.generateSecret(pbeKeySpec);
SecretKey secret = new SecretKeySpec(tmp.getEncoded(), SECRET_KEY_ALGORITHM);
return secret;
} catch (Exception e) {
throw new CryptoException("Unable to get secret key", e);
}
}
public String getHash(String password, String salt) throws CryptoException {
try {
String input = password + salt;
MessageDigest md = MessageDigest.getInstance(HASH_ALGORITHM, PROVIDER);
byte[] out = md.digest(input.getBytes("UTF-8"));
return HexEncoder.toHex(out);
} catch (Exception e) {
throw new CryptoException("Unable to get hash", e);
}
}
public String generateSalt() throws CryptoException {
try {
SecureRandom random = SecureRandom.getInstance(RANDOM_ALGORITHM);
byte[] salt = new byte[SALT_LENGTH];
random.nextBytes(salt);
String saltHex = HexEncoder.toHex(salt);
return saltHex;
} catch (Exception e) {
throw new CryptoException("Unable to generate salt", e);
}
}
private byte[] generateIv() throws NoSuchAlgorithmException, NoSuchProviderException {
SecureRandom random = SecureRandom.getInstance(RANDOM_ALGORITHM);
byte[] iv = new byte[IV_LENGTH];
random.nextBytes(iv);
return iv;
}
}
स्रोत: http://pocket-for-android.1047292.n5.nabble.com/Enc एन्क्रिप्शन-method- and- reading-the-Dropbox-backup-td4344194.html
कार्यान्वयन # 2:
import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
/**
* Usage:
* <pre>
* String crypto = SimpleCrypto.encrypt(masterpassword, cleartext)
* ...
* String cleartext = SimpleCrypto.decrypt(masterpassword, crypto)
* </pre>
* @author ferenc.hechler
*/
public class SimpleCrypto {
public static String encrypt(String seed, String cleartext) throws Exception {
byte[] rawKey = getRawKey(seed.getBytes());
byte[] result = encrypt(rawKey, cleartext.getBytes());
return toHex(result);
}
public static String decrypt(String seed, String encrypted) throws Exception {
byte[] rawKey = getRawKey(seed.getBytes());
byte[] enc = toByte(encrypted);
byte[] result = decrypt(rawKey, enc);
return new String(result);
}
private static byte[] getRawKey(byte[] seed) throws Exception {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
sr.setSeed(seed);
kgen.init(128, sr); // 192 and 256 bits may not be available
SecretKey skey = kgen.generateKey();
byte[] raw = skey.getEncoded();
return raw;
}
private static byte[] encrypt(byte[] raw, byte[] clear) throws Exception {
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
byte[] encrypted = cipher.doFinal(clear);
return encrypted;
}
private static byte[] decrypt(byte[] raw, byte[] encrypted) throws Exception {
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
byte[] decrypted = cipher.doFinal(encrypted);
return decrypted;
}
public static String toHex(String txt) {
return toHex(txt.getBytes());
}
public static String fromHex(String hex) {
return new String(toByte(hex));
}
public static byte[] toByte(String hexString) {
int len = hexString.length()/2;
byte[] result = new byte[len];
for (int i = 0; i < len; i++)
result[i] = Integer.valueOf(hexString.substring(2*i, 2*i+2), 16).byteValue();
return result;
}
public static String toHex(byte[] buf) {
if (buf == null)
return "";
StringBuffer result = new StringBuffer(2*buf.length);
for (int i = 0; i < buf.length; i++) {
appendHex(result, buf[i]);
}
return result.toString();
}
private final static String HEX = "0123456789ABCDEF";
private static void appendHex(StringBuffer sb, byte b) {
sb.append(HEX.charAt((b>>4)&0x0f)).append(HEX.charAt(b&0x0f));
}
}
स्रोत: http://www.tutorials-android.com/learn/How_to_encrypt_and_decrypt_str..html