当前位置: 首页 > 知识库问答 >
问题:

如何在angularJs中生成AES/CBC/PKCS5Padding加密密码

方嘉言
2023-03-14

我正在开发一个功能,需要Aes加密(Aes/CBC/PKCS5Padding)密码文本从客户端发送到后端有ASP.NET的服务器。

我在服务器端有一个解密功能如下:

 public static string Decrypt(string inputBase64, string passphrase = null)
                {
                    byte[] key, iv = new byte[0];
                    byte[] base64data = Convert.FromBase64String(inputBase64);
                    byte[] passphrasedata = RawBytesFromString(passphrase);
                    byte[] currentHash = new byte[0];
                    SHA256Managed hash = new SHA256Managed();
                    currentHash = hash.ComputeHash(passphrasedata);
                    return DecryptStringFromBytes(base64data, currentHash, null);
                }



static string DecryptStringFromBytes(byte[] cipherText, byte[] Key, byte[] IV)
        {
            // Check arguments. 
            if (cipherText == null || cipherText.Length <= 0)
                throw new ArgumentNullException("cipherText");
            if (Key == null || Key.Length <= 0)
                throw new ArgumentNullException("Key");
            //if (IV == null || IV.Length <= 0)
            //  throw new ArgumentNullException("Key");

            // Declare the string used to hold 
            // the decrypted text. 
            string plaintext = null;

            // Create an RijndaelManaged object 
            // with the specified key and IV. 
            using (var cipher = new RijndaelManaged())
            {
                cipher.Key = Key;
                cipher.IV = new byte[16];
                //cipher.Mode = CipherMode.CBC;
                //cipher.Padding = PaddingMode.PKCS7;

                // Create a decrytor to perform the stream transform.
                ICryptoTransform decryptor = cipher.CreateDecryptor(Key, cipher.IV);

                // Create the streams used for decryption. 
                using (MemoryStream msDecrypt = new MemoryStream(cipherText))
                {
                    using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                    {
                        var bytes = default(byte[]);
                        using (StreamReader srDecrypt = new StreamReader(csDecrypt))
                        {
                            bytes = srDecrypt.CurrentEncoding.GetBytes(srDecrypt.ReadToEnd());

                            // Read the decrypted bytes from the decrypting stream 
                            // and place them in a string.
                            //aintext = srDecrypt.ReadToEnd();
                        }
                        plaintext = ASCIIEncoding.UTF8.GetString(bytes, 0, bytes.Count());
                    }
                }

            }

            return plaintext;

        }
public static String Encrypt(String input, String passphrase)
    {
        if (input.equalsIgnoreCase("") || passphrase.equalsIgnoreCase(""))
            return "";
        else
        {
            byte[] key, iv;

            byte[] passphrasedata = null;
            try
            {
                passphrasedata = passphrase.getBytes("UTF-8");
            }
            catch (UnsupportedEncodingException e1)
            {
                e1.printStackTrace();
            }
            byte[] currentHash = new byte[0];
            MessageDigest md = null;
            try
            {
                md = MessageDigest.getInstance("SHA-256");
            }
            catch (NoSuchAlgorithmException e)
            {
                e.printStackTrace();
            }
            currentHash = md.digest(passphrasedata);

            iv = new byte[16];
            return Base64.encodeToString(EncryptStringToBytes(input, currentHash, iv), Base64.NO_WRAP);
        }
    }

static byte[] EncryptStringToBytes(String plainText, byte[] Key, byte[] IV)
    {
        if (plainText == null || plainText.length() <= 0)
        {
            Log.e("error", "plain text empty");
        }
        if (Key == null || Key.length <= 0)
        {
            Log.e("error", "key is empty");
        }
        if (IV == null || IV.length <= 0)
        {
            Log.e("error", "IV key empty");
        }
        byte[] encrypted;

        try
        {
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            SecretKeySpec myKey = new SecretKeySpec(Key, "AES");
            IvParameterSpec IVKey = new IvParameterSpec(IV);
            cipher.init(Cipher.ENCRYPT_MODE, myKey, IVKey);

            encrypted = cipher.doFinal(plainText.getBytes("UTF-8"));
            return encrypted;
        }
        catch (InvalidKeyException e)
        {
            e.printStackTrace();
        }
        catch (NoSuchAlgorithmException e)
        {
            e.printStackTrace();
        }
        catch (NoSuchPaddingException e)
        {
            e.printStackTrace();
        }
        catch (InvalidAlgorithmParameterException e)
        {
            e.printStackTrace();
        }
        catch (IllegalBlockSizeException e)
        {
            e.printStackTrace();
        }
        catch (BadPaddingException e)
        {
            e.printStackTrace();
        }
        catch (UnsupportedEncodingException e)
        {
            e.printStackTrace();
        }
        return null;
    }

我包含了用于SHA-256和AES密码计算的CryptoJS库。下面是我实现的代码。

var password = '12345678';
var passwordHash = CryptoJS.SHA256(password).toString(CryptoJS.enc.Latin1);
var iv = CryptoJS.enc.Hex.parse('0000000000000000');                                                                       
var cipher = CryptoJS.AES.encrypt(plaintext,passwordHash,{
                            iv: iv,
                            mode: CryptoJS.mode.CBC,
                            keySize: 256/32,
                            padding: CryptoJS.pad.Pkcs7
                            });
cipherText = cipher.ciphertext.toString(CryptoJS.enc.Base64);

问题是,编码后的字符串不能解密回其以前的形式。我认为客户端的加密逻辑和服务器端的解密逻辑存在一定的不匹配。

当我将CryptoJS加密密码传递给java解密函数时,它显示错误:

或者有时:

BadPaddingException:给定的最终块没有正确填充

共有1个答案

唐阳飇
2023-03-14

谢谢伙计们!!!,我用下面的代码得到了它。

    function hash (){
       return CryptoJS.SHA256(password);
    }
    var cipher = (function(plaintext, password) {
                        passwordHash = hash(password);
                        var iv = CryptoJS.enc.Hex.parse('0000000000000000');
                        var cipher = CryptoJS.AES.encrypt(plaintext, passwordHash, {
                            iv: iv,
                            mode: CryptoJS.mode.CBC,
                            keySize: 256 / 32,
                            padding: CryptoJS.pad.Pkcs7
                        });
                        return cipher;
    })(plaintext, password);

   cipherBase64 =  cipher.ciphertext.toString().hex2a().base64Encode();
 类似资料:
  • 问题内容: 我正在尝试在java中加密数据并在ruby中解密数据。 我的代码是…用Java加密 结果是 我希望在Ruby中解密(加密的字符串) Ruby代码是…(错误) 我希望得到 但它返回错误 我认为问题是cipher.padding和key / iv的类型。但是我不知道如何完成红宝石代码。 请让我知道如何完成此代码。 谢谢。 问题答案: Ruby代码有两个问题。 首先,应该使用AES 128时

  • 问题内容: 我正在尝试在NodeJs中解密。它在Java中工作。但是我无法在Node中实现相同的功能。 节点版本:8.4 请找到我的NodeJs代码: 请找到有效的Java解密代码 我得到了不同的解密文本。在NodeJ中,我无法获得与Java中相同的结果。另外,我无法修改Java加密代码。所以我必须弄清楚Node中的解密。 你能帮我这个忙吗? 问题答案: 这是Java和Node.js中的完整示例,

  • 我使用JavaAPI生成128bit密钥。下面是我使用的算法: 我可以通过这些方法轻松地使用secretKey加密和解密消息。由于Java默认使用128bit AES加密,因此它使用SHA1生成原始密钥的哈希,并将哈希的前16字节用作AES中的密钥。然后以十六进制格式转储IV和密文。 但是,它返回一个空字符串。

  • 我有一些问题,解密文本的CryptoJS已经用Java加密。解密应使用AES/CBC/PKCS5Padding完成。加密的字符串是base64编码的,我在尝试解密字符串之前对其进行解码。 这就是Java代码的样子:

  • 我希望有一个用C编写的程序,可以在没有openssl这样的大型库的帮助下,用AES-CBC对字符串进行编码/解码。 目标: 使用密码短语对字符串进行编码/解码: 因此,应用程序需要接受3个输入参数。。。 输入字符串(待编码)/或已编码字符串(待解码) 用于编码/解码字符串的密码 编码或解码指示器 我对C语言不熟悉(我可以用C#编码)。 我已经找到了https://github.com/kokke/