I want to encrypt the data in flutter using the AES cbc-128 algorithm. below is the java code for that i want to achieve the same functionality as below but in dart. i have tried
cryptography
dependency in flutter but the problem with that is that i want to use my own key in the algorithm as below in the java code. if you know any method for achieving this please let me know.
public static String Decrypt(String text, String key) throws Exception {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
byte[] keyBytes = new byte[16];
byte[] b = key.getBytes("UTF-8");
int len = b.length;
if (len > keyBytes.length)
len = keyBytes.length;
System.arraycopy(b, 0, keyBytes, 0, len);
SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");
IvParameterSpec ivSpec = new IvParameterSpec(keyBytes);
cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
BASE64Decoder decoder = new BASE64Decoder();
byte[] results = cipher.doFinal(decoder.decodeBuffer(text));
return new String(results, "UTF-8");
}
public static String Encrypt(String text, String key) throws Exception {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
byte[] keyBytes = new byte[16];
byte[] b = key.getBytes("UTF-8");
int len = b.length;
if (len > keyBytes.length)
len = keyBytes.length;
System.arraycopy(b, 0, keyBytes, 0, len);
SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");
IvParameterSpec ivSpec = new IvParameterSpec(keyBytes);
cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
byte[] results = cipher.doFinal(text.getBytes("UTF-8"));
BASE64Encoder encoder = new BASE64Encoder();
return encoder.encode(results);
}
Test Case
For the following input
plainText="This is plain text";
key="sahtojetrout2";
i want the encrypted result to be
encryptedText="8FmSMnDsFJVyNUXunhJLSmhFnRq89fl5DyTp0wdYfgk=";
which Topaco has written in an online editor you can check out that here Java Code. In flutter i have tried the program given at the Flutter site
You can do AES CBC-128 encryption in flutter with the help of crypt library. It supports the AES cbc encryption. The following sample code accepts key-string and plain-text as arguments and encrypts it as you have mentioned. You can pass your own key here. For AES-128, you need 128 bit key or 16 character string.
import 'package:encrypt/encrypt.dart';
void main() {
final key = "Your16CharacterK";
final plainText = "lorem ipsum example example";
Encrypted encrypted = encrypt(key, plainText);
String decryptedText = decrypt(key, encrypted);
print(decryptedText);
}
String decrypt(String keyString, Encrypted encryptedData) {
final key = Key.fromUtf8(keyString);
final encrypter = Encrypter(AES(key, mode: AESMode.cbc));
final initVector = IV.fromUtf8(keyString.substring(0, 16));
return encrypter.decrypt(encryptedData, iv: initVector);
}
Encrypted encrypt(String keyString, String plainText) {
final key = Key.fromUtf8(keyString);
final encrypter = Encrypter(AES(key, mode: AESMode.cbc));
final initVector = IV.fromUtf8(keyString.substring(0, 16));
Encrypted encryptedData = encrypter.encrypt(plainText, iv: initVector);
return encryptedData;
}
In the above example, the IV is created from the key itself to keep the code easy to read. Use random data for IV for better security. Referred article for flutter encryption.
Related
Currently having issues with the decryption of an AES hash.
When i encrypt using AES256 i get the following result (After base64 encoding)
07sKQfb9dN86XAMxFmVKHQAAAAAAAAAAAAAAAAAAAAA=
I believe my issue is with the AAAAAAAA etc. for some reason I think anyway the padding isn't being removed during decryption.
My code
public String encrypt(String key, String initVector, String value) throws Exception {
IvParameterSpec iv = new IvParameterSpec(initVector.getBytes("UTF-8"), 0, initVector.getBytes().length);
SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), 0, key.getBytes().length, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
byte[] encrypted = new byte[32];
cipher.doFinal(value.getBytes(), 0, value.getBytes().length, encrypted, 0);
System.out.println("Base64: " + Base64.encode(encrypted));
System.out.println("Hex: " + bytesToHex(encrypted));
return Base64.encode(encrypted);
}
public String decrypt(String key, String initVector, String encrypted) {
try {
IvParameterSpec iv = new IvParameterSpec(initVector.getBytes("UTF-8"), 0, initVector.getBytes().length);
SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), 0, key.getBytes().length, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
byte[] decrypted = new byte[64];
cipher.doFinal(Base64.decode(encrypted), 0, Base64.decode(encrypted).length, decrypted, 0);
return new String(decrypted);
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
What i am expecting when i encode base64 07sKQfb9dN86XAMxFmVKHQ=
String i am encrypting: Test
Secret key: password12345678password12345678
byte[] decrypted = new byte[64];
you created a 64 byte array but the decrypted value may be shorter (Java doesn't use zero string terminator unlike C does). So you should not make assumption over the parameter length
try using
encrypted = cipher.doFinal(value.getBytes());
and
decrypted = cipher.doFinal(Base64.decode(encrypted));
Someone can help me with aes cbc algorithm? I have some method which return string more than 192 chars but I need to get 192!
I use next method. I've read a lot of articles but I don't get it how to do that.. Maybe someone have some instance how to resolve it?? I used to web aes encrypted http://www.cryptogrium.com/aes-encryption-online-ecb.html and I got 192 chars, but I can't do that with my method
private static byte[] iv = "0000000000000000".getBytes();
public static String encrypt(String content, String key) throws Exception {
byte[] input = content.getBytes("utf-8");
MessageDigest md = MessageDigest.getInstance("SHA-256");
byte[] thedigest = md.digest(key.getBytes("utf-8"));
SecretKeySpec skc = new SecretKeySpec(thedigest, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, skc, new IvParameterSpec(iv));
byte[] cipherText = new byte[cipher.getOutputSize(input.length)];
int ctLength = cipher.update(input, 0, input.length, cipherText, 0);
ctLength += cipher.doFinal(cipherText, ctLength);
return DatatypeConverter.printHexBinary (cipherText);
}
I want to use JAVA encryption and decryption logic in qt creator code i tried and search lot of stuff but success for "DES/CBC" Encryption and Decryption Logic but not useful for me Because JAVA code is in "DESede/CBC/PKCS5Padding" Triple DES logic.
JAVA CODE is as follows:
public static String initializationVector = "abhijeet";
public static String key="XB13347FE570DC4FFB13647F";
public String encryptText(String plainText) throws Exception {
// ---- Use specified 3DES key and IV from other source --------------
byte[] plaintext = plainText.getBytes();
byte[] tdesKeyData = Config.key.getBytes();
// byte[] myIV = initializationVector.getBytes();
Cipher c3des = Cipher.getInstance("DESede/CBC/PKCS5Padding");
SecretKeySpec myKey = new SecretKeySpec(tdesKeyData, "DESede");
IvParameterSpec ivspec = new IvParameterSpec(Config.initializationVector.getBytes());
c3des.init(Cipher.ENCRYPT_MODE, myKey, ivspec);
byte[] cipherText = c3des.doFinal(plaintext);
return new BASE64Encoder().encode(cipherText);
}
public static String decryptText(String cipherText) throws Exception {
byte[] encData = new BASE64Decoder().decodeBuffer(cipherText);
Cipher decipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
byte[] tdesKeyData = Config.key.getBytes();
SecretKeySpec myKey = new SecretKeySpec(tdesKeyData, "DESede");
IvParameterSpec ivspec = new IvParameterSpec(Config.initializationVector.getBytes());
decipher.init(Cipher.DECRYPT_MODE, myKey, ivspec);
byte[] plainText = decipher.doFinal(encData);
return new String(plainText);
}
Example :
Input string - "Hello"
After Encryption Output string - "c13FZpr4odg="
Please Help for the same as i stuck here
I use aes-256-cbc for data encrypt/decrypt.
When decrypt data with php code i'm not getting an error.
Php code like this:
$key = 'd7df7d66bc110ba2e03a3a647ecd8c3f';
$iv = '73e8c03a24b4bb1e';
$encrypt_method = "AES-256-CBC";
$encrypted_text = "K0JOVFQreEQ4TlRjWGwyNXBhejRtQWVWU2doVkRsUjkvaEhQamlRdWRIWWpQQ0dVWmNpNTJXR3hhbXdWbDN4WGJpcGZTblpHRVpyeGpDY2lLc3o4cGJEeHdwdmZDTUlxalRyeDdVYlB4SmJtVUhEQkVSN3VZSklWb2h0dlZkYmY=";
$output = openssl_decrypt(base64_decode($data), $encrypt_method, $key, 0, $iv);
output:
{"Sayfa":"b2pneVd4bUcQT09","TelNo":"905373603204","Sifre":"9cbf8a4dcb8e30682b927f352d6559a0"}
But when decrypt data with android ( java ) code i getting an error like this:
javax.crypto.IllegalBlockSizeException:Cipher functions:OPENSSL_internal:WRONG_FINAL_BLOCK_LENGTH
Java code :
String key = "d7df7d66bc110ba2e03a3a647ecd8c3f";
String iv = "73e8c03a24b4bb1e";
String encryptedText = "K0JOVFQreEQ4TlRjWGwyNXBhejRtQWVWU2doVkRsUjkvaEhQamlRdWRIWWpQQ0dVWmNpNTJXR3hhbXdWbDN4WGJpcGZTblpHRVpyeGpDY2lLc3o4cGJEeHdwdmZDTUlxalRyeDdVYlB4SmJtVUhEQkVSN3VZSklWb2h0dlZkYmY=";
AESUtil.decrypt(encryptedText,key,iv);
public String decrypt(String encryptedText, String key, String iv) {
byte[] cipheredBytes = Base64.decode(encryptedText,Base64.DEFAULT);
byte[] keyBytes = getKeyBytes(key);
byte[] ivBytes = getIvBytes(iv);
return new String(decrypt(cipheredBytes, keyBytes, ivBytes), "UTF-8");
}
public byte[] decrypt(byte[] cipherText, byte[] key, byte [] initialVector) {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");
IvParameterSpec ivParameterSpec = new IvParameterSpec(initialVector);
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
return cipher.doFinal(cipherText);
}
private byte[] getIvBytes(String iv) {
byte[] keyBytes= new byte[16];
byte[] parameterKeyBytes= iv.getBytes(characterEncoding);
System.arraycopy(parameterKeyBytes, 0, keyBytes, 0, Math.min(parameterKeyBytes.length, keyBytes.length));
return keyBytes;
}
private byte[] getKeyBytes(String key){
byte[] keyBytes= new byte[32];
byte[] parameterKeyBytes= key.getBytes(characterEncoding);
System.arraycopy(parameterKeyBytes, 0, keyBytes, 0, Math.min(parameterKeyBytes.length, keyBytes.length));
return keyBytes;
}
where is the error in java code?
I don't have Android, and on regular Java (Oracle JavaSE 8) after replacing that Base64 decoder with the Oracle one I don't get that error, but I do get BadPaddingException because your data is actually double base64 encoded. In your PHP this works because you decode explicitly once, then openssl_decrypt with options=0 does the second decode.
In Java if I base64-decode the data twice (and use key and IV directly as bytes, as PHP did, even though they look like they should be hex-decoded) it does decrypt successfully and as expected. According to the doc on developer.android.com I think Android's Base64.DEFAULT is the same as Oracle's default, but I can't verify that myself.
I have generated on my android application a pair of RSA Keys.
I receive from a web service
- an AES Key, encrypted with my RSA public key
- a String encoded with the AES key.
So I must do the following:
- decrypt the AES Key
- decrypt the string with the obtained AES Key.
To generate the RSA Keys I did:
keyGen = KeyPairGenerator.getInstance("RSA");
keyGen.initialize(size);
keypair = keyGen.genKeyPair();
privateKey = keypair.getPrivate();
publicKey = keypair.getPublic();
On RSA decrypt I use :
public static byte[] decryptRSA( PrivateKey key, byte[] text) throws Exception
{
byte[] dectyptedText = null;
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, key);
dectyptedText = cipher.doFinal(text);
return dectyptedText;
}
On AES decrypt I use:
public static byte[] decryptAES(byte[] key, byte[] text) throws Exception {
SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
byte[] decrypted = cipher.doFinal(text);
return decrypted;
}
So, in my code, to obtain the decrypted AES Key I do
byte[] decryptedAESKey = sm.decryptRSA(key, Base64.decode(ReceivedBase64EncryptedAESKey));
byte[] decryptedString = sm.decryptAES(decryptedAESKey, Base64.decode(ReceivedEncryptedAESString));
On the end I get a null for decryptedString.
What am I doing wrong ?
Well, the thing is that the key decrypted was 8 byte long and I had to make it 16 byte to be AES 128 bits compatible
So, I made a method to convert it back
private static byte[] GetKey(byte[] suggestedKey)
{
byte[] kRaw = suggestedKey;
ArrayList<Byte> kList = new ArrayList<Byte>();
for (int i = 0; i < 128; i += 8)
{
kList.add(kRaw[(i / 8) % kRaw.length]);
}
byte[] byteArray = new byte[kList.size()];
for(int i = 0; i<kList.size(); i++){
byteArray[i] = kList.get(i);
}
return byteArray;
}
And the rewritten decrypt method:
public static byte[] decryptAES(byte[] key, byte[] text) throws Exception {
SecretKeySpec skeySpec = new SecretKeySpec(GetKey(key), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding","BC");
byte [] iv = new byte[cipher.getBlockSize()];
for(int i=0;i<iv.length;i++)iv[i] = 0;
IvParameterSpec ivSpec = new IvParameterSpec(iv);
cipher.init(Cipher.DECRYPT_MODE, skeySpec, ivSpec);
byte[] decrypted = cipher.doFinal(text);
return decrypted;
}
I'm not sure what language or libraries you are using (looks like Java?), but some really general things to try:
Did you get the encrypted string, ok? Check the length of ReceivedEncryptedAESString and the output of the Base64.decode to check they look alright.
AES decryption can't fail so it must be a problem in the library initialisation. Check the value/state of cipher after the construction step and the init step.
Try a simpler testcase: ignore the RSA encryption and just try to decrypt something using your Cipher object.