【问题标题】:Encrypting with CryptoJS using Triple DES in ECB mode and PKCS#5 padding在 ECB 模式下使用三重 DES 和 PKCS#5 填充使用 CryptoJS 进行加密
【发布时间】:2019-07-02 06:39:15
【问题描述】:

我在发送到需要在 ECB 模式下使用 PKCS#5 填充进行三重 DES 加密的第 3 方 API 之前对字符串进行加密。他们给了我一个示例字符串来加密

www.society.com|1084470043000|会员访问

的示例键

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. 我需要对我的密钥进行 base 64 加密,然后才能像这样使用它。

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

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

【问题讨论】:

  • PKCS#5 和 PKCS#7 在这里相同,只有 PKCS#7 supports 块大小超过 64 位。你能问他们的输出格式吗?你用 base64 呢?
  • 真正的问题?示例输入是 society.org,而不是 society.com

标签: javascript encryption cryptography cryptojs


【解决方案1】:

来自 CryptoJS 文档:

对于密钥,当您传递一个字符串时,它会被视为密码并用于派生实际密钥和 IV。或者您可以传递一个代表实际键的 WordArray。如果传递实际密钥,则还必须传递实际 IV。

您应该将密钥十六进制解码为一个字数组,并将一个 16 字节的 IV 设置为所有零字节。欧洲央行不使用IV,但请务必注明。否则key会从字符串派生,这显然会导致不正确的结果。

【讨论】:

  • 我会根据您的建议工作。如果您有代码示例来帮助我连接点,我将不胜感激。
  • 抱歉,周末放假。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-31
相关资源
最近更新 更多