Java解码AES编码的消息问题

时间:2017-11-30 07:07:44

标签: javascript java aes cryptojs

这是我的java程序:

package com.util;

import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Base64;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;

public class Coder1 {

    public static int AES_KEY_SIZE = 256 ;
    public static int IV_SIZE = 16 ;
    public static void main(String[] args) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException 
    {
        String message = "abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
        message =message +message;
        message =message +message;
        KeyGenerator keygen = KeyGenerator.getInstance("AES") ; // Specifying algorithm key will be used for 
        keygen.init(AES_KEY_SIZE) ; // Specifying Key size to be used, Note: This would need JCE Unlimited Strength to be installed explicitly 
        SecretKey aesKey = keygen.generateKey();

        // Generating IV
        byte iv[] = new byte[IV_SIZE];

        SecureRandom secRandom = new SecureRandom() ;
        secRandom.nextBytes(iv);
        Cipher cipher = Cipher.getInstance("AES/CTR/PKCS5PADDING");
        Cipher decipher = Cipher.getInstance("AES/CTR/PKCS5PADDING");
        cipher.init(Cipher.ENCRYPT_MODE, aesKey,new IvParameterSpec(iv));
        decipher.init(Cipher.DECRYPT_MODE, aesKey,new IvParameterSpec(iv));
        byte[] cipherTextInByteArr = cipher.doFinal(message.getBytes());
        byte[] plainTextInByteArr = decipher.doFinal(cipherTextInByteArr);
        System.out.println("Key="+Base64.getEncoder().encodeToString(aesKey.getEncoded())+"|");
        System.out.println("IV="+Base64.getEncoder().encodeToString(iv)+"|");
        System.out.println("Encrypted Text=" + Base64.getEncoder().encodeToString(cipherTextInByteArr)+"|") ;
        System.out.println("Decrypted text=" + new String(plainTextInByteArr));
    }

}

为了解码上述java程序的输出,我应该使用哪个javascript库?我想设置一个安全的websocket频道。 我尝试过使用RSA算法。不幸的是,它不支持大于128字节的消息大小。

我按照here中的示例进行操作。它在java方面运行良好,但是,我不知道如何将SealedObject发送到javascript端,因此,再次死路一条。

java程序输出如下:

Key=hlnUjh4GM1PegSzl13YFQgI5+I1qcbsmqlBV8vDsVy0=|
IV=ZkqiRuDS7YUrjZMLRr/gfQ==|
Encrypted Text=HFROj40Qh9YagJAS+7saN2/ugqszCPpmjT9Qwy2yt9dCntSbpbYqTt/tW0ju5QO614+S9zQyOdBXFKtNdDew9Ouo9YkmRgRkjY7NNGyVbt+Z5CYCgcwpRmNUuH7Fqyat5H3hFSUi05UyLLA6lIa47wyP7jKsq0rtj1yHth8qN06aisB18s4Cf9YBPbUM72qXS+IcpKLMWEVVw7Q0qA91WRCt9y93SptNUme75D/qCKyym20UJ5f0ZCgijOnnsbWJKci1R179qZ8UthFBjqcZm88VmV1UuA7OsAvzxsyA7iVtwsf9u6UnrlOtoMTl41Q5nLod4unkdbomrXb6hDKhV9ThtCy1ZWPFHhKbEAPMdzUnmmBSwcuGSTKvdPJeHAWH|
Decrypted text=abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890

根据帖子here,Crypto-JS可以成功解码Java输出。

然而,java程序无法成功解码javascript输出。 这是我的javascript progarm

    <script src="js/cryptojs/rollups/aes.js"></script>
    <script src="js/cryptojs/components/mode-ctr-min.js"></script>
    <script language=javascript>
          ..................
      var result;
      var encoded=CryptoJS.AES.encrypt("hello",
                                       keyArray,
                                       {
                                         iv: ivArray,
                                         mode: CryptoJS.mode.CTR,
                                         padding: CryptoJS.pad.Pkcs7
                                        });

      result=encoded.ciphertext.toString(CryptoJS.enc.Base64);
   </script>

我的java程序:

   byte iv[] = new byte[16];
   SecureRandom secRandom = new SecureRandom() ;
   secRandom.nextBytes(iv);       
   Cipher decipher = Cipher.getInstance("AES/CTR/PKCS5PADDING");
   decipher.init(Cipher.DECRYPT_MODE, aesKey,new IvParameterSpec(iv)); 
   byte[] cipherTextInByteArr =Base64.getDecoder().decode(encodedText);
   byte[] plainTextInByteArr = decipher.doFinal(cipherTextInByteArr);     
   String result=new String(plainTextInByteArr,"UTF-8");

然而,输出是&#34;你好???????&#34;。    有什么不对吗?

1 个答案:

答案 0 :(得分:0)

最后,我明白了。 根据{{​​3}},点击率模式不需要填充。 因此javascript程序看起来像:

<script src="js/cryptojs/rollups/aes.js"></script>
<script src="js/cryptojs/components/mode-ctr-min.js"></script>
<script language=javascript>
      ..................
  var result;
  var encoded=CryptoJS.AES.encrypt("hello",
                                   keyArray,
                                   {
                                     iv: ivArray,
                                     mode: CryptoJS.mode.CTR,
                                     padding: CryptoJS.pad.NoPadding
                                    });

  result=encoded.ciphertext.toString(CryptoJS.enc.Base64);
</script>

java程序看起来像:

byte iv[] = new byte[16];
SecureRandom secRandom = new SecureRandom() ;
secRandom.nextBytes(iv);       
Cipher decipher = Cipher.getInstance("AES/CTR/NoPadding");
decipher.init(Cipher.DECRYPT_MODE, aesKey,new IvParameterSpec(iv)); 
byte[] cipherTextInByteArr =Base64.getDecoder().decode(encodedText);
byte[] plainTextInByteArr = decipher.doFinal(cipherTextInByteArr);     
String result=new String(plainTextInByteArr,"UTF-8");