Я пытаюсь зашифровать/дешифровать с помощью AES256 с использованием Java для шифрования и CryptoJS для дешифрования. Шифрование проверено в Java is Работает отлично, но метод дешифрования в JavaScript возвращает пустую строку. Обратите внимание, что для проверки JavaScript я распечатал в файле tmp значения для данных, IV и соли, а затем жестко закодировал в JS. (Примечание: формат в файле: data (byte [] base64), Iv (строка base64) и соль (строка base64)).Метод расшифровки CryptoJs возвращает пустую строку
Вот код в Java:
public byte[] encrypt(String plainText) throws Exception {
//get salt
salt = generateSalt();
byte[] saltBytes = salt.getBytes("UTF-8");
// Derive the key
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
PBEKeySpec spec = new PBEKeySpec(
password.toCharArray(),
saltBytes,
pswdIterations,
keySize
);
SecretKey secretKey = factory.generateSecret(spec);
SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(), "AES");
//encrypt the message
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secret);
AlgorithmParameters params = cipher.getParameters();
ivBytes = params.getParameterSpec(IvParameterSpec.class).getIV();
byte[] encryptedTextBytes = cipher.doFinal(plainText.getBytes("UTF-8"));
return Base64.encode(encryptedTextBytes);
}
, что не так с кодом дешифрования в JavaScript ниже?
// the password that user provides
var userPass = document.getElementById("password").value;
console.log("user pass : " + userPass);
// hash contains 5 bytes
var hashedPass = CryptoJS.SHA1(userPass);
console.log("hashed pass : " + hashedPass.toString(CryptoJS.enc.Base64) + " | array length " + hashedPass.words.length + " | " + typeof(hashedPass));
// use only 4 bytes (128 bits) from the hashed pass
// (same as used in java when encrypting)
/////////////////////////var hashed4bytes = CryptoJS.lib.WordArray.create(hashedPass.words.slice(0,4));
//console.log("hashed4bytes encoded 64 = " + hashed4bytes.toString(CryptoJS.enc.Base64));
// get the encrypted msg
var encMsg64 = document.getElementById("themessage").innerHTML;
encMsg64 = encMsg64.toString(CryptoJS.enc.Base64);
//var encMsg = CryptoJS.enc.Base64.parse(encMsg64);
var salt =CryptoJS.enc.Base64.parse("EAWnOgxUDuvhWqrSUsugq1umMpI=");
var iv =CryptoJS.enc.Base64.parse("xWpmXNbmbFjmWBUajuWYXQ==");
//var salt = "EAWnOgxUDuvhWqrSUsugq1umMpI=";
//var iv = "xWpmXNbmbFjmWBUajuWYXQ==";
console.log('salt '+ salt);
console.log('iv '+ iv);
var key = CryptoJS.PBKDF2(hashedPass, salt, { keySize: 256/32, iterations: 1000 });
console.log('key '+ key);
var decText = '';
var ok = true;
try {
debugger;
var decMsg = CryptoJS.AES.decrypt(encMsg64, key, {
iv:iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
console.log("decryptedData = " + decMsg);
// convert to UTF8 string
decText = decMsg.toString(CryptoJS.enc.Utf8);
console.log("decryptedText = " + decText);
if (decText == '') {
ok = false;
}
}
catch (e) {
//console.log("Error when decrypting: " + e.message)
ok = false;
}
после Mafe измененная проблема все еще сохраняется Вот полный код после изменения
JAVA
public class AES256EncryptionServiceBean implements EncryptionService {
private static final Logger LOGGER = LoggerFactory
.getLogger(AES256EncryptionServiceBean.class);
private String salt = null; //get bytes out of UTF-8 for decryption
private static final int PSWDITERATIONS = 1000;//65536;
private static final int KEYSIZE = 256;
private static final String AES_ALGO = "AES";
private static final String SHA1_ALGO = "PBKDF2WithHmacSHA1";
private static final String AES_CBC_PKCS5_TRANSFORM = "AES/CBC/PKCS5Padding";
private byte[] Iv;
/**
* Encrypts the data with AES-256 algorithm Encrypted data will be encoded
* with base64 algorithm and the returned. Initial vector is being used
* during encryption along with CBC encryption mode.
*
* output format: [algo indicator(1char)][Initialization vector()][salt()][encoded data(variable size)]
*/
@Override
public byte[] encrypt(String password, byte[] data) throws PibException {
byte[] encodedData = null;
try {
byte[] encryptedData = encryptCBC256Bits(password, data);
encodedData = Base64.encodeBase64(encryptedData);
/*String finalStr=null;
String algo256 = "2";
String datastr = Base64.encodeBase64String(encryptedData);
String ivstr = new String(Iv);
finalStr = algo256 +ivstr+salt+datastr;
encodedData = finalStr.getBytes();
*/
} catch (Exception e) {
throw ExceptionFactory.createPibException(
MessageCodes.PIB_ENCRYPTION_FAILED, e, LOGGER);
}
return encodedData;
}
/**
* Encrypts the input data with AES CBC transformation using 256 bits (32
* bytes) Key is generated based on the provided password and random salt.
* Salt is the extra bits added to the password to ensure every key is
* unique SHA1 hashing is also participate in key generation.
*
* @throws PibException
*
*/
private byte[] encryptCBC256Bits(String password, byte[] data)
throws PibException {
salt = generateSalt();
byte[] saltBytes = salt.getBytes(StandardCharsets.UTF_8);
byte[] encryptedTextBytes = null;
// Derive the key
try {
SecretKeyFactory factory = SecretKeyFactory.getInstance(SHA1_ALGO);
// Password based key specification
PBEKeySpec spec = new PBEKeySpec(password.toCharArray(), saltBytes,
PSWDITERATIONS, KEYSIZE);
SecretKey secretKey = factory.generateSecret(spec);
SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(),
AES_ALGO);
// encrypt the data
Cipher cipher = Cipher.getInstance(AES_CBC_PKCS5_TRANSFORM);
// SecureRandom random = new SecureRandom();
// byte[] ivTemp = new byte[16];
// random.nextBytes(ivTemp);
cipher.init(Cipher.ENCRYPT_MODE, secret);
AlgorithmParameters params = cipher.getParameters();
Iv = params.getParameterSpec(IvParameterSpec.class).getIV();
encryptedTextBytes = cipher.doFinal(data);
} catch (NoSuchAlgorithmException | InvalidKeySpecException
| NoSuchPaddingException | InvalidKeyException
| InvalidParameterSpecException | IllegalBlockSizeException
| BadPaddingException e) {
throw ExceptionFactory.createPibException(
MessageCodes.PIB_ENCRYPTION_FAILED, e, LOGGER);
}
return encryptedTextBytes;
}
private String generateSalt() {
SecureRandom random = new SecureRandom();
byte bytes[] = new byte[20];
random.nextBytes(bytes);
String s = new String(bytes);
return s;
}
public String getSalt() {
return salt;
}
public byte[] getIv() {
return Iv;
}
}
Javascript
function decryptMsg256() {
// the password that user provides
var userPass = document.getElementById("password").value;
console.log("user pass : " + userPass);
// get the encrypted msg
var encMsg64 = document.getElementById("themessage").innerHTML;
var encMsg = CryptoJS.enc.Base64.parse(encMsg64);
var salt =CryptoJS.enc.Utf8.parse("?E€O5?…°®I^y??O:n");
var iv =CryptoJS.enc.Utf8.parse("S;Ui?¨=ENzI—$");
console.log('salt '+ salt);
console.log('iv '+ iv);
var key = CryptoJS.PBKDF2("password", salt, { keySize: 256/32, iterations: 1000 });
console.log('key '+ key);
var decText = '';
var ok = true;
try {
debugger;
var decMsg = CryptoJS.AES.decrypt(encMsg, key, {
iv:iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
console.log("decryptedData = " + decMsg);
// convert to UTF8 string
decText = decMsg.toString(CryptoJS.enc.Utf8);
console.log("decryptedText = " + decText);
if (decText == '') {
ok = false;
}
}
catch (e) {
//console.log("Error when decrypting: " + e.message)
ok = false;
}
я не могу понимает, что это не так, пожалуйста, помогите зашифрованного текста, соль и Iv извлекается следующим образом:
public void testEncryption_WriteToFile() throws Exception {
byte[] data = IOUtils.toByteArray(this.getClass().getClassLoader()
.getResourceAsStream(SOME_FILE_NAME));
byte[] encryptedData = this.encryptionService.encrypt(PASSWORD, data);
byte[] initial_vector = ((AES256EncryptionServiceBean) encryptionService)
.getIv();
String salt = ((AES256EncryptionServiceBean) encryptionService)
.getSalt();
IOUtils.write(encryptedData, new FileOutputStream(
"C:\\Temp\\data.encrypted"));
/*IOUtils.write(new String(encryptedData), new FileOutputStream(
"C:\\Temp\\data[byte32string].encrypted"));
*/
IOUtils.write(Base64.encodeBase64String(salt.getBytes(StandardCharsets.UTF_8)), new FileOutputStream(
"C:\\Temp\\salt.encrypted"));
/*IOUtils.write(salt.getBytes(StandardCharsets.UTF_8), new FileOutputStream(
"C:\\Temp\\salt.encrypted"));
*/
IOUtils.write(Base64.encodeBase64String(initial_vector), new FileOutputStream(
"C:\\Temp\\iv.encrypted"));
/*IOUtils.write(initial_vector, new FileOutputStream(
"C:\\Temp\\iv.encrypted"));*/
}
Большое спасибо за ответ. Я использую пароль в Js, так как я использую «PBKDF2WithHmacSHA1» для генерации ключей на Java, это неверно? Я использую toString вместо Base64.parse, поскольку сообщение уже находится в base64, поскольку оно возвращается из java (byte [] base64), это тоже не правильно? – marios390
К сожалению, после того, как измененная проблема по-прежнему сохраняется (возвращает пустую строку): – marios390
Вы представили новую проблему, см. Мой обновленный ответ. Вы подтвердили, что генерируете один и тот же ключ? Кроме того, это не полный код.Вы не показали, как вы получите шифрованный текст, соль и IV из кода Java. –