Android
पासवर्ड को सुरक्षित रूप से कैसे स्टोर करें
खोज…
नमकीन पासवर्ड एन्क्रिप्शन के लिए एईएस का उपयोग करना
यह उदाहरण पासवर्ड एन्क्रिप्ट करने के लिए एईएस एल्गोरिथ्म का उपयोग करता है। नमक की लंबाई 128 बिट तक हो सकती है।
हम एक नमक उत्पन्न करने के लिए SecureRandom
क्लास का उपयोग कर रहे हैं, जो एक गुप्त कुंजी उत्पन्न करने के लिए पासवर्ड के साथ संयुक्त है। इस्तेमाल की गई कक्षाएं पहले से ही एंड्रॉइड पैकेज javax.crypto
और java.security
।
एक बार एक कुंजी उत्पन्न होने के बाद, हमें इस कुंजी को एक चर में संरक्षित करना होगा या इसे स्टोर करना होगा। हम इसे S_KEY
मान में साझा प्राथमिकताओं के बीच संग्रहीत कर रहे हैं। फिर, एक पासवर्ड का उपयोग कर एन्क्रिप्टेड है doFinal
की विधि Cipher
वर्ग एक बार यह में initialised है ENCRYPT_MODE
। इसके बाद, एन्क्रिप्ट किया गया पासवर्ड एक बाइट सरणी से एक स्ट्रिंग में परिवर्तित हो जाता है और साझा प्राथमिकताओं के बीच संग्रहीत होता है। एन्क्रिप्टेड पासवर्ड जेनरेट करने के लिए उपयोग की जाने वाली कुंजी का उपयोग पासवर्ड को समान तरीके से डिक्रिप्ट करने के लिए किया जा सकता है:
public class MainActivity extends AppCompatActivity {
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";
public static final String SECRET_KEY_ALGORITHM = "AES";
private static final String TAG = "EncryptionPassword";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String originalPassword = "ThisIsAndroidStudio%$";
Log.e(TAG, "originalPassword => " + originalPassword);
String encryptedPassword = encryptAndStorePassword(originalPassword);
Log.e(TAG, "encryptedPassword => " + encryptedPassword);
String decryptedPassword = decryptAndGetPassword();
Log.e(TAG, "decryptedPassword => " + decryptedPassword);
}
private String decryptAndGetPassword() {
SharedPreferences prefs = getSharedPreferences("pswd", MODE_PRIVATE);
String encryptedPasswrd = prefs.getString("token", "");
String passwrd = "";
if (encryptedPasswrd!=null && !encryptedPasswrd.isEmpty()) {
try {
String output = prefs.getString("S_KEY", "");
byte[] encoded = hexStringToByteArray(output);
SecretKey aesKey = new SecretKeySpec(encoded, SECRET_KEY_ALGORITHM);
passwrd = decrypt(aesKey, encryptedPasswrd);
} catch (Exception e) {
e.printStackTrace();
}
}
return passwrd;
}
public String encryptAndStorePassword(String password) {
SharedPreferences.Editor editor = getSharedPreferences("pswd", MODE_PRIVATE).edit();
String encryptedPassword = "";
if (password!=null && !password.isEmpty()) {
SecretKey secretKey = null;
try {
secretKey = getSecretKey(password, generateSalt());
byte[] encoded = secretKey.getEncoded();
String input = byteArrayToHexString(encoded);
editor.putString("S_KEY", input);
encryptedPassword = encrypt(secretKey, password);
} catch (Exception e) {
e.printStackTrace();
}
editor.putString("token", encryptedPassword);
editor.commit();
}
return encryptedPassword;
}
public static String encrypt(SecretKey secret, String cleartext) throws Exception {
try {
byte[] iv = generateIv();
String ivHex = byteArrayToHexString(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 = byteArrayToHexString(encryptedText);
return ivHex + encryptedHex;
} catch (Exception e) {
Log.e("SecurityException", e.getCause().getLocalizedMessage());
throw new Exception("Unable to encrypt", e);
}
}
public static String decrypt(SecretKey secret, String encrypted) throws Exception {
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(hexStringToByteArray(ivHex));
decryptionCipher.init(Cipher.DECRYPT_MODE, secret, ivspec);
byte[] decryptedText = decryptionCipher.doFinal(hexStringToByteArray(encryptedHex));
String decrypted = new String(decryptedText, "UTF-8");
return decrypted;
} catch (Exception e) {
Log.e("SecurityException", e.getCause().getLocalizedMessage());
throw new Exception("Unable to decrypt", e);
}
}
public static String generateSalt() throws Exception {
try {
SecureRandom random = SecureRandom.getInstance(RANDOM_ALGORITHM);
byte[] salt = new byte[SALT_LENGTH];
random.nextBytes(salt);
String saltHex = byteArrayToHexString(salt);
return saltHex;
} catch (Exception e) {
throw new Exception("Unable to generate salt", e);
}
}
public static String byteArrayToHexString(byte[] b) {
StringBuffer sb = new StringBuffer(b.length * 2);
for (int i = 0; i < b.length; i++) {
int v = b[i] & 0xff;
if (v < 16) {
sb.append('0');
}
sb.append(Integer.toHexString(v));
}
return sb.toString().toUpperCase();
}
public static byte[] hexStringToByteArray(String s) {
byte[] b = new byte[s.length() / 2];
for (int i = 0; i < b.length; i++) {
int index = i * 2;
int v = Integer.parseInt(s.substring(index, index + 2), 16);
b[i] = (byte) v;
}
return b;
}
public static SecretKey getSecretKey(String password, String salt) throws Exception {
try {
PBEKeySpec pbeKeySpec = new PBEKeySpec(password.toCharArray(), hexStringToByteArray(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 Exception("Unable to get secret key", e);
}
}
private static byte[] generateIv() throws NoSuchAlgorithmException, NoSuchProviderException {
SecureRandom random = SecureRandom.getInstance(RANDOM_ALGORITHM);
byte[] iv = new byte[IV_LENGTH];
random.nextBytes(iv);
return iv;
}
}