Typescript 中的加密 ( Angular ) 和 Java 中的解密

Encryption in Typescript ( Angular ) and Decryption in Java

我目前正在使用 Angular7。 我有 Java 客户端提供的加密、解密代码,我需要在 Angular.

下面是 Java.

的代码
import java.security.SecureRandom;
import java.security.spec.KeySpec;
import java.util.Base64;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;

里面Class我有

class EnDc(String passPhrase)
{
    private static final byte[] SALT = { 8 random numbers between -127 to 127 };
    private static final int ITERATION_COUNT = 1000;
    private static final int KEY_LENGTH = 256;
    private static final int IV_LENGTH = 16;
    private Cipher eCipher;
    private Cipher dCipher;
    private byte[] encrypt;
    private byte[] iv;

哈希密钥和iv的生成如下:

    SecretKeyFactory secretKeyFactory = 
            SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
    KeySpec keySpec = new PBEKeySpec(passPhrase.toCharArray(), SALT, 
            1000, 256);

他们已经使用密钥规范生成了临时密钥,如下所示:

    secretKeyTemp = secretKeyFactory.generateSecret(keySpec);

使用临时密钥和 "AES"

生成了新密钥
    secretKey = new SecretKeySpec(secretKeyTemp.getEncoded(), //encode 
            "AES");

后续步骤:

    this.eCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    this.eCipher.init(1, secretKey);
    // 1 - ENCRYPT_MODE, 2 - DECRYPT_MODE

第四代:

    this.iv = ((IvParameterSpec)this.eCipher.getParameters().getParameterSpec(IvParameterSpec.class)).getIV();

}

实际加密函数如下

public String encrypt(String encrypt)
      {
        String encStr = null;
        try
        {
          byte[] bytes = encrypt.getBytes("UTF8");
          byte[] encrypted = encrypt(bytes);
          byte[] cipherText = new byte[encrypted.length + this.iv.length];
          System.arraycopy(this.iv, 0, cipherText, 0, this.iv.length);
          System.arraycopy(encrypted, 0, cipherText, this.iv.length, encrypted.length);
          encStr = new String(Base64.getEncoder().encode(cipherText));
        }
        catch (Exception ex)
        {
          ex.printStackTrace();
        }
        return encStr;
      }

我正在尝试在 Angular 的服务文件中实现这个,根据我的理解,SALT 字节数组是预定义的,IV 是随机的,它附加在加密字符串之前并在解密时提取,

所以我尝试的 JS 方式如下

import * as CryptoJS from 'crypto-js';

encrypt (msg, pass) {
  const salt = CryptoJS.lib.WordArray.random(128 / 8);

  const key = CryptoJS.PBKDF2( pass, salt, {
      keySize: this.keySize / 32,
      iterations: this.iterations
  });

  const iv =  CryptoJS.lib.WordArray.random(128 / 8);
  const encrypted = CryptoJS.AES.encrypt(msg, key, {
    iv: iv,
    padding: CryptoJS.pad.Pkcs7,
    mode: CryptoJS.mode.CBC
  });

  const transitmessage = salt.toString() + iv.toString() + encrypted.toString();
  return transitmessage;
}

所以,我已经完成了 link http://www.adonespitogo.com/articles/encrypting-data-with-cryptojs-aes/ 中的这段代码,所以现在的问题是如何实现硬编码在 JAVA 以及 [=60] 中的 SALT =] 代码他们没有发送带有加密字符串的盐密钥,但 IV 仅作为前 16 位。我该如何实施?

我试过这样做

salt = CryptoJS.lib.WordArray.create([-67, -85, 13, -28, 75, 112, -126, 103]);

但生成的密钥是对象,而且我在解密时遇到错误

编辑 1:我希望 salt 每次都相同,我当前随机生成并附加到加密字符串。

我不知道 Javascript

是否有一些 SecretKeyFactory 和 Keyspec 的实现

感谢帮助,提前致谢。

当您执行以下操作时,WordArray.create 方法将您的数字用作 32 位整数:

salt = CryptoJS.lib.WordArray.create([-67, -85, 13, -28, 75, 112, -126, 103]);

在这种情况下,您的十六进制盐是:

ffffffbdffffffab0000000dffffffe40000004b00000070ffffff8200000067

如果将 javascript Array 对象转换为 Int8Array,CryptoJS 将创建与 Java:

中相同的盐
salt = CryptoJS.lib.WordArray.create(new Int8Array([-67, -85, 13, -28, 75, 112, -126, 103]));

结果:

bdab0de44b708267

如果适合您,请查找以下解决方案。

encrypt (msg, pass) {
    const key = CryptoJS.PBKDF2(pass, this.salt, {
        keySize: this.keySize / 32,
        iterations: this.iterations
    });

    const iv =  CryptoJS.lib.WordArray.random(128 / 8);

    const encrypted = CryptoJS.AES.encrypt(msg, key, {
          iv: iv,
          padding: CryptoJS.pad.Pkcs7,
          mode: CryptoJS.mode.CBC
    });

    const transitmessage = iv + encrypted.ciphertext;
    var tm=CryptoJS.enc.Hex.parse(transitmessage); // This converts to Type Word which is required for below function as input
    return CryptoJS.enc.Base64.stringify(tm); // Encoding
}