问题
Not data encrypt only show Null, pls change code if any mistake. i think problem is my key and iv, but i dont no how to creat it pls hellp me
String text = Java_AES_Cipher.encrypt("123sadsad","123","vishal");
Log.i("encrypt_Text is = ", "" + text);
public static String encrypt(String key, String iv, String data) {
try {
if (key.length() < Java_AES_Cipher.CIPHER_KEY_LEN) {
int numPad = Java_AES_Cipher.CIPHER_KEY_LEN - key.length();
for(int i = 0; i < numPad; i++){
key += "0"; //0 pad to len 16 bytes
}
} else if (key.length() > Java_AES_Cipher.CIPHER_KEY_LEN) {
key = key.substring(0, CIPHER_KEY_LEN); //truncate to 16 bytes
}
IvParameterSpec initVector = new IvParameterSpec(iv.getBytes("UTF-8"));
SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
Cipher cipher = Cipher.getInstance(Java_AES_Cipher.CIPHER_NAME);
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, initVector);
byte[] encryptedData = cipher.doFinal((data.getBytes()));
String base64_EncryptedData = Base64.getEncoder().encodeToString(encryptedData);
String base64_IV = Base64.getEncoder().encodeToString(iv.getBytes("UTF-8"));
return base64_EncryptedData + ":" + base64_IV;
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
Not data encrypt only show Null, pls change code if any mistake.
回答1:
import android.util.Base64;
import javax.crypto.Cipher;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.security.GeneralSecurityException;
import java.security.MessageDigest;
import javax.crypto.spec.SecretKeySpec;
import java.util.Arrays;
import javax.crypto.spec.IvParameterSpec;
public class Decrypter {
public static byte[] generateKey() throws GeneralSecurityException, UnsupportedEncodingException {
final String KEY = "com.taba.notes";
byte[] binary = KEY.getBytes("UTF-8");
MessageDigest sha = MessageDigest.getInstance("SHA-1");
binary = sha.digest(binary);
// Use only first 128 bit.
binary = Arrays.copyOf(binary, 16);
return binary;
}
public static String encrypt(byte[] key, String value) throws GeneralSecurityException {
// Argument validation.
if (key.length != 16) {
throw new IllegalArgumentException("Invalid key size.");
}
SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, new IvParameterSpec(new byte[16]));
byte[] original = value.getBytes(Charset.forName("UTF-8"));
byte[] binary = cipher.doFinal(original);
return Base64.encodeToString(binary, Base64.DEFAULT);
}
public static String decrypt(byte[] key, String encrypted) throws GeneralSecurityException {
// Argument validation.
if (key.length != 16) {
throw new IllegalArgumentException("Invalid key size.");
}
// Setup AES tool.
SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, skeySpec, new IvParameterSpec(new byte[16]));
byte[] binary = Base64.decode(encrypted, Base64.DEFAULT);
byte[] original = cipher.doFinal(binary);
return new String(original, Charset.forName("UTF-8"));
}
}
Example:
try{
byte[] key = Decrypter.generateKey();
String title = Decrypter.decrypt( key, note.getTitle() );
deleteFolder( title, position );
} catch(Exception e) {
e.printStackTrace();
}
回答2:
Your method returns null because it throws an exception on the cipher.init method.
In ENCRYPT_MODE you're not supposed to supply an initialization vector.
The initialization vector is needed in order to DECRYPT the data and not encrypt it.
Try this instead:
public static Key getKey(String keyAlias) {
KeyStore keystore = KeyStore.getInstance("AndroidKeyStore");
keystore.load(null);
if(keystore.containsAlias(keyAlias)){
return keyStore.getKey(keyAlias, null);
}
KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore")
KeyGenParameterSpec.Builder builder =
KeyGenParameterSpec.Builder(keyAlias, KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
.setBlockModes(KeyProperties.BLOCK_MODE_CBC)
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7);
KeyGenParameterSpec keyGenParameterSpec = builder.build();
keyGenerator.init(keyGenParameterSpec);
//this creates the key and stores it in AndroidKeyStore for later use
return keyGenerator.generateKey();
}
public static String encrypt(String keyAlias, String data) {
try {
SecretKey key = getKey(keyAlias);
Cipher cipher = Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES+"/"+KeyProperties.BLOCK_MODE_CBC+"/"+KeyProperties.ENCRYPTION_PADDING_PKCS7);
cipher.init(Cipher.ENCRYPT_MODE, key);
//you need to store the iv (maybe in shared preferences)
//in order to be able to decrypt the data
//The IV is auto generated by the cipher, you don't need to create it
//for every encrypt operation the IV is different
IvParameterSpec initVector = cipher.getIv();
byte[] encryptedData = cipher.doFinal((data.getBytes()));
String base64_EncryptedData = Base64.getEncoder().encodeToString(encryptedData);
//do not add the IV to the encrypted data, store it along side the data instead
return base64_EncryptedData;
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
public static byte[] decrypt(String keyAlias, String base64EncryptedData, byte[] iv) {
SecretKey key = getKey(keyAlias);
Cipher cipher = Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES+"/"+KeyProperties.BLOCK_MODE_CBC+"/"+KeyProperties.ENCRYPTION_PADDING_PKCS7);
//here you actually need the IV
cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv));
byte[] dataToDecrypt = Base64.Decoder().decodeString(base64EncryptedData);
byte[] decryptedData = cipher.doFinal(dataToDecrypt);
return decryptedData;
}
PS. very nice idea to post this question as a comment to one of my previous answers :)
来源:https://stackoverflow.com/questions/59092141/android-text-encryption-with-key-iv-data