在ECB模式和PKCS#5填充中使用Triple DES使用CryptoJS进行加密

时间:2019-02-08 02:38:04

标签: javascript encryption cryptography cryptojs

我正在加密字符串,然后再发送给需要使用PKCS#5填充的ECB模式下的三重DES加密的第三方API。他们给了我一个示例字符串以加密

  

www.society.com | 1084470043000 | memberaccess

和示例键

  

92f2f81930b5afb056630afb02f2f8b1

生成的加密字符串应匹配

  

uQlYYov + XlVEHL0JBpvt15FeJxt + fXgjs9KLJHH5XsUd80emx5Nn5kSaCXxhQId /

但是我收到的字符串是

  

U2FsdGVkX19 / IR4A9cm + duXf3vhnmnuyJtXFVWJi / Ptqib7g5gOANppYXh + mTQ8tcenO58a5FxnFVxRq1PUETA ==

我正在使用这些库

<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9/crypto-js.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9/tripledes.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9/mode-ecb.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9/pad-pkcs7.js"></script>

这是我的代码

var encrypted = CryptoJS.TripleDES.encrypt("www.society.com|1084470043000|memberaccess" , "92f2f81930b5afb056630afb02f2f8b1", {
        mode: CryptoJS.mode.ECB,
        padding: CryptoJS.pad.Pkcs7
    });

我意识到我指定的是PKCS#7而不是PKCS#5,但是我还没有找到PKCS#5的库。

我的问题是使用CryptoJS是否可以满足他们的要求,如果不能,是否还有其他可用的javascript解决方案?

我的小提琴

https://jsfiddle.net/dwc6zb89/2/

我没有在密码学上花费足够的时间来给您一个关于是否为base64的好答案。我相信是因为我编写的C#代码块几乎可以产生正确的结果。还差几个字符。我正在继续比较两者,以查看我的c#代码在做什么,而javascript不是。

public static string Encrypt(string toEncrypt, bool useHashing)
{
    var key = "92f2f81930b5afb056630afb02f2f8b1";

    var iso8859_1 = System.Text.Encoding.GetEncoding("iso-8859-1");

    var keyArray = Convert.FromBase64String(iso8859_1.GetString(iso8859_1.GetBytes(key)));


    byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(toEncrypt);




    if (useHashing)
    {
        MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider();

        //Always release the resources and flush data
        // of the Cryptographic service provide. Best Practice

        hashmd5.Clear();
    }
    else
        keyArray = UTF8Encoding.UTF8.GetBytes(key);

    TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
    //set the secret key for the tripleDES algorithm
    tdes.Key = keyArray;
    //mode of operation. there are other 4 modes.
    //We choose ECB(Electronic code Book)
    tdes.Mode = CipherMode.ECB;
    //padding mode(if any extra byte added)

    tdes.Padding = PaddingMode.PKCS7;

    ICryptoTransform cTransform = tdes.CreateEncryptor();
    //transform the specified region of bytes array to resultArray
    byte[] resultArray =
      cTransform.TransformFinalBlock(toEncryptArray, 0,
      toEncryptArray.Length);
    //Release resources held by TripleDes Encryptor
    tdes.Clear();
    //Return the encrypted data into unreadable string format
    return Convert.ToBase64String(resultArray, 0, resultArray.Length);
}

更新:

我感觉自己很疯狂。通过使用以下

转换我的密钥
var encryptedKey = CryptoJS.enc.Base64.parse(key);

我能够生成一个加密值,该值与供应商给我的样本仅相差几个字符。这是我目前的小提琴。

https://jsfiddle.net/uv8z2mrc/1/

更新:

我有两个问题。

  1. 像这样使用密钥之前,我需要对64位密钥进行加密。

    var encryptionKey = CryptoJS.enc.Base64.parse(key);

  2. 供应商文档错误,加密值应该使用.org而不是.com地址。 GRRR!

1 个答案:

答案 0 :(得分:0)

来自CryptoJS文档:

  

对于密钥,当您传递字符串时,将其视为密码短语并用于派生实际的密钥和IV。或者,您可以传递代表实际键的WordArray。如果您通过了实际密钥,那么您还必须通过实际IV。

您应该将密钥十六进制解码为一个字数组,还应将一个16字节的IV设置为所有零字节。欧洲央行未使用IV,但是请务必指定。否则,密钥将从字符串中派生,这显然会导致错误的结果。