问题
I have to implement encryption in android app. The web developer is using CryptoJs library. means Encryption alog is AES256 encryption.
Both iOS and android platforms give different strings and iOS one is accepted at web.It should be same for sample strings.
I am using below code snippets (there are 2 different diffrent functions):
private void newEnc() {
String secret = "LSC@SD2017@ps";
String cipherText = "{\"device_type\":\"iOS\",\"email\" : \"jhon@gmail.com\",\"device_id\" : \"14105DA4-CEE5-431E-96A2-2331CDA7F062\",\"password\" : \"123456\",\"device_token\" : \"B44777563552882EC3139A0317E401B55D6FC699D0AC3D279F392927CAF9B566\"}";
KeyGenerator kgen = null;
try {
kgen = KeyGenerator.getInstance("AES");
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
sr.setSeed(secret.getBytes("UTF8"));
kgen.init(256, sr);
SecretKey skey = kgen.generateKey();
Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding");
SecretKeySpec skeySpec = new SecretKeySpec(skey.getEncoded(), "AES");
c.init(Cipher.ENCRYPT_MODE, skeySpec);
byte[] decrypted = c.doFinal(cipherText.getBytes());
System.out.println(Base64.encodeToString(decrypted, Base64.NO_WRAP));
// decrypted = Base64.encodeBase64(decrypted);
// byte[] iv = Base64.encodeBase64(c.getIV());
// Log.e("encryptString", new String(decrypted));
// Log.d("encryptString iv", new String(iv));
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
}
}
I also used :
private void enctest(String cipherText) {
String secret = "LSC@SD2017@ps";
// String cipherText = "{\"device_type\":\"iOS\",\"email\" : \"jhon@gmail.com\",\"device_id\" : \"14105DA4-CEE5-431E-96A2-2331CDA7F062\",\"password\" : \"123456\",\"device_token\" : \"B44777563552882EC3139A0317E401B55D6FC699D0AC3D279F392927CAF9B566\"}";
MessageDigest md5 = null;
try {
// String cipherText = "U2FsdGVkX1+tsmZvCEFa/iGeSA0K7gvgs9KXeZKwbCDNCs2zPo+BXjvKYLrJutMK+hxTwl/hyaQLOaD7LLIRo2I5fyeRMPnroo6k8N9uwKk=";
byte[] cipherData = Base64.decode(cipherText.getBytes(), Base64.NO_WRAP);
byte[] saltData = Arrays.copyOfRange(cipherData, 8, 16);
md5 = MessageDigest.getInstance("MD5");
final byte[][] keyAndIV = GenerateKeyAndIV(32, 16, 1, saltData, secret.getBytes("UTF-8"), md5);
SecretKeySpec key = new SecretKeySpec(keyAndIV[0], "AES");
IvParameterSpec iv = new IvParameterSpec(keyAndIV[1]);
byte[] encrypted = Arrays.copyOfRange(cipherData, 16, cipherData.length);
Cipher aesCBC = Cipher.getInstance("AES/CBC/PKCS5Padding");
aesCBC.init(Cipher.ENCRYPT_MODE, key, iv);
byte[] decryptedData = aesCBC.doFinal(cipherText.getBytes("UTF-8"));
// String plainText = "Hello, World! This is a Java/Javascript AES test.";
// SecretKey key = new SecretKeySpec(
// Base64.decodeBase64("u/Gu5posvwDsXUnV5Zaq4g=="), "AES");
// AlgorithmParameterSpec iv = new IvParameterSpec(
// Base64.decodeBase64("5D9r9ZVzEYYgha93/aUK2w=="));
// Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
// cipher.init(Cipher.ENCRYPT_MODE, key, iv);
// System.out.println(Base64.encodeBase64String(cipher.doFinal(
// plainText.getBytes("UTF-8"))));
// String decryptedText = new String(decryptedData, "UTF-8");
System.out.println(Base64.encodeToString(decryptedData, Base64.NO_WRAP));
// enctest(decryptedText);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (InvalidAlgorithmParameterException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
But none gives the same results.
in iOS they are using https://github.com/etienne-martin/CryptoJS.swift
What should I do that both of our encrypted strings match.
回答1:
The actual cipherText
(not to be confused the character string with the same variable name) is formatted and starts with "Salted__" and presumably encryption parameters. The two different functions create different outputs with different formats. They can not produce the same output.
Note 1, confusing cipherText
:
// String cipherText = "{\"device_type\":\"iOS\",\"email\" : \"jhon@gmail.com\",\"device_id\" : \"14105DA4-CEE5-431E-96A2-2331CDA7F062\",\"password\" : \"123456\",\"device_token\" : \"B44777563552882EC3139A0317E401B55D6FC699D0AC3D279F392927CAF9B566\"}";
// String cipherText = "U2FsdGVkX1+tsmZvCEFa/iGeSA0K7gvgs9KXeZKwbCDNCs2zPo+BXjvKYLrJutMK+hxTwl/hyaQLOaD7LLIRo2I5fyeRMPnroo6k8N9uwKk=";
Note 2:
Base64 is so un-useful for humans, it is designed for computers, hex is for humans and computers with a direct bits to bytes correspondence.
来源:https://stackoverflow.com/questions/45936706/cryptojs-encryption-is-not-working-in-android