2016-12-25 16 views
0

У меня есть следующие функции написаны на JavaScript, для шифрования с использованием AES-256-GCM:Tag ошибка несоответствия в AES-256-GCM Расшифровка с использованием Java

encrypt: function (text, masterkey){ 
    try { 
     // random initialization vector 
     var iv = crypto.randomBytes(12); 

     // random salt 
     var salt = crypto.randomBytes(64); 

     // derive key: 32 byte key length - in assumption the masterkey is a cryptographic and NOT a password there is no need for 
     // a large number of iterations. It may can replaced by HKDF 
     var key = crypto.pbkdf2Sync(masterkey, salt, 2145, 32, 'sha512'); 

     // AES 256 GCM Mode 
     var cipher = crypto.createCipheriv('aes-256-gcm', key, iv); 

     // encrypt the given text 
     var encrypted = Buffer.concat([cipher.update(text, 'utf8'), cipher.final()]); 

     // extract the auth tag 
     var tag = cipher.getAuthTag(); 

     // generate output 
     return Buffer.concat([salt, iv, tag, encrypted]).toString('base64'); 

    }catch(e){ 
    } 

    // error 
    return null; 
} 

зашифрованный текст функцией выше успешно расшифрованы назад с помощью следующей функции:

decrypt: function (data, masterkey){ 
    try { 
     // base64 decoding 
     var bData = new Buffer(data, 'base64'); 
     var salt = bData.slice(0, 64); 
     var iv = bData.slice(64, 76); 
     var tag = bData.slice(76, 92); 
     var text = bData.slice(92); 

     // derive key using; 32 byte key length 
     var key = crypto.pbkdf2Sync(masterkey, salt , 2145, 32, 'sha512'); 
     // AES 256 GCM Mode 
     var decipher = crypto.createDecipheriv('aes-256-gcm', key, iv); 
     decipher.setAuthTag(tag); 

     // decrypt the given text 
     var decrypted = decipher.update(text, 'binary', 'utf8') + decipher.final('utf8'); 

     return decrypted; 

    }catch(e){ 
    } 

    // error 
    return null; 
} 

Теперь мне нужен метод в Java для дешифрования, который является эквивалентом функции выше Javascript расшифровывать. Ниже приводится код Java я написал для дешифрования:

public void decrypt(byte[] nkb, String crKey){ 
    //nkb is byte array formed by Base64 decoding of 'data' variable in the Javascript code 
    //crKey corresponds to the 'masterkey' variable 

    byte[] salt = Arrays.copyOfRange(nkb, 0, 64); 
    byte[] iv = Arrays.copyOfRange(nkb, 64, 76); 
    byte[] tag = Arrays.copyOfRange(nkb, 76, 92); 
    byte[] text = Arrays.copyOfRange(nkb, 92, nkb.length); 

    PBEKeySpec ks = new PBEKeySpec(crKey.toCharArray(), salt, iterations, 256); 
    SecretKeyFactory skf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA512"); 
    SecretKey pbeKey = skf.generateSecret(ks); 

    byte[] decrypted = decrypt(iv, pbeKey.getEncoded(), text, tag); 
} 
    public static byte[] decrypt(byte[] ivBytes, byte[] keyBytes, byte[] textBytes, byte[] tagBytes) 
     throws java.io.UnsupportedEncodingException, 
     NoSuchAlgorithmException, 
     NoSuchPaddingException, 
     InvalidKeyException, 
     InvalidAlgorithmParameterException, 
     IllegalBlockSizeException, 
     BadPaddingException, 
     NoSuchProviderException { 

     GCMParameterSpec ivSpec = new GCMParameterSpec(tagBytes.length*Byte.SIZE, ivBytes); 

     SecretKeySpec newKey = new SecretKeySpec(keyBytes, "AES"); 

     Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding"); 
     cipher.init(Cipher.DECRYPT_MODE, newKey, ivSpec); 
     return cipher.doFinal(textBytes); //getting tag mismatch error here 
    } 

Как я уже отметил, в приведенном выше коде, я получаю ошибку рассогласования Tag в последней строке. Я был бы признателен за помощь в выяснении того, что я делаю неправильно.

У меня есть ошибка в этой строке кода:

cipher.init(Cipher.DECRYPT_MODE, newKey, ivSpec) 
java.security.InvalidKeyException: Illegal key size 
at javax.crypto.Cipher.checkCryptoPerm(Cipher.java:1039) 
at javax.crypto.Cipher.implInit(Cipher.java:805) 
at javax.crypto.Cipher.chooseProvider(Cipher.java:864) 
at javax.crypto.Cipher.init(Cipher.java:1396) 
at javax.crypto.Cipher.init(Cipher.java:1327) 
at com.micropro.namwebservice.utils.CryptoUtils.decrypt(CryptoUtils.java:93) 
at com.micropro.namwebservice.utils.CryptoUtils.decrypt(CryptoUtils.java:82) 

ответ

1

Вы должны предоставить тег в код Java GCM так, что он может проверить, что сообщение является подлинным. API Java ожидает, что тег будет добавлен к зашифрованному тексту. Самый простой способ изменить свой код, чтобы сделать это было бы заменить строку

return cipher.doFinal(textBytes); 

с двумя линиями:

cipher.update(textBytes); 
return cipher.doFinal(tagBytes); 
+0

Он отлично работает спасибо. Означает ли это, что байты тегов добавляются в конце текстовых байтов? –

+0

@AnishHirlekar да, Java ожидает, что байты зашифрованного текста сразу же будут следовать за байтами тега, и проверит соответствие тега, выбрасывая исключение, если это не так. – matt

-1
cipher.init(Cipher.DECRYPT_MODE, newKey, ivSpec); // Error in this line 

java.security.InvalidKeyException: Illegal key size 
at javax.crypto.Cipher.checkCryptoPerm(Cipher.java:1039) 
at javax.crypto.Cipher.implInit(Cipher.java:805) 
at javax.crypto.Cipher.chooseProvider(Cipher.java:864) 
at javax.crypto.Cipher.init(Cipher.java:1396) 
at javax.crypto.Cipher.init(Cipher.java:1327) 
at com.micropro.namwebservice.utils.CryptoUtils.decrypt(CryptoUtils.java:93) 
at com.micropro.namwebservice.utils.CryptoUtils.decrypt(CryptoUtils.java:82) 
+0

Добавить свое описание. – Kuls

+0

Когда я вызов метода decrypt(), чем java.security.InvalidKeyException: Неверный размер ключа – Ram

 Смежные вопросы

  • Нет связанных вопросов^_^