首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用预定义的密钥和IV在TripleDES中进行python3加密?

如何使用预定义的密钥和IV在TripleDES中进行python3加密?
EN

Stack Overflow用户
提问于 2020-09-23 19:51:51
回答 2查看 940关注 0票数 0

由于遗留的C#.NET代码,我不能更改密钥和IV,它们只是它们本身。但我似乎找不到办法去做我需要做的事。我试过这个..。

代码语言:javascript
复制
strToEncrypt = "Please encrypt me."
ivStr = "AStringOfIV="
keyStr = "aKeyOfSomeKindThat+IWillNotShare"

cipher = DES3.new(keyStr, DES3.MODE_CFB, IV=ivStr)
encryptedStr = cipher.iv + cipher.encrypt(strToEncrypt)

这告诉我"IV必须有8个字节长“。

我的不是,也不可能。所以很显然这行不通。我也试过这个:

代码语言:javascript
复制
m=hashlib.md5()
print(sys.getsizeof(iv))
m.update(bytes(keyStr, 'UTF-8'))
k = pyDes.triple_des(m.digest(),pyDes.CBC,IV=iv,padmode=pyDes.PAD_PKCS5)
encryptedStr = k.encrypt(strToEncrypt)

这告诉我“无效的初始值(IV),必须是8个字节的倍数”。

我调整了ivStr变量,如上面所示,使用getsizeof()检查它,以查看会发生什么:

代码语言:javascript
复制
ivStr = "AStringOfIV===="

我得到了同样的消息,“无效初始值(IV),必须是8个字节的倍数”。但是..。它是。这次又是什么?

我尝试以字节的形式直接传递它,无论是原始的ivStr还是64字节的字节,都带有额外的等号。

代码语言:javascript
复制
k = pyDes.triple_des(
    keyStr,
    mode=pyDes.CBC,
    IV=bytes(ivStr, 'UTF-8'),
    pad=None,
    padmode=pyDes.PAD_PKCS5
)
encryptedStr = k.encrypt(strToEncrypt)

我得到了同样的消息,“无效初始值(IV),必须是8个字节的倍数”。是我告诉你的!

我试过pyDes.CBC和pyDes.ECB,想知道这会不会有什么不同。我看不见。

根据下面评论中@ShadowRanger的建议,我将初始代码改为添加b64decodeb64encode,如下所示:

代码语言:javascript
复制
pyDes.triple_des(m.digest(),pyDes.CBC,IV=base64.b64decode(ivStr),padmode=pyDes.PAD_PKCS5)
encryptedStr = base64.b64encode(k.encrypt(strToEncrypt))

这确实消除了我得到的8字节错误,并产生了一个字符串结果,但是,字符串结果与C#程序产生的结果不匹配,所以我还没有到达终点线。

作为参考,如果有用的话,将对我加密的字符串使用的C#.NET解密代码(以及最初用于加密它的旧C#.NET代码)如下:

代码语言:javascript
复制
using System;
using System.Security.Cryptography;
using System.Text;

namespace encryption
{
    class Program
    {
        const string IV = "AStringOfIV=";
        const string Key = "aKeyOfSomeKindThat+IWillNotShare";

        public static string Encrypt(string data)
        {
            byte[] buffer = Encoding.UTF8.GetBytes(data);
            TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
            ICryptoTransform transform = tdes.CreateEncryptor(Convert.FromBase64String(Key), Convert.FromBase64String(IV));
            byte[] result = transform.TransformFinalBlock(buffer, 0, buffer.Length);
            string encrypted = BitConverter.ToString(result).Replace("-", "");
            return encrypted;
        }

        public static string Decrypt(string data)
        {
            byte[] result = StringToByteArray(data);
            TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
            ICryptoTransform transform = tdes.CreateDecryptor(Convert.FromBase64String(Key), Convert.FromBase64String(IV));
            byte[] originalBytes = transform.TransformFinalBlock(result, 0, result.Length);
            string original = Encoding.UTF8.GetString(originalBytes);
            return original;
        }

        public static byte[] StringToByteArray(String hex)
        {
            int NumberChars = hex.Length / 2;
            byte[] bytes = new byte[NumberChars];
            using (var sr = new System.IO.StringReader(hex))
            {
                for (int i = 0; i < NumberChars; i++)
                {
                    string thisByte = new string(new char[2] { (char)sr.Read(), (char)sr.Read() });
                    bytes[i] = Convert.ToByte(thisByte, 16);
                }
            }
            return bytes;
        }

        static void Main(string[] args)
        {
            Console.WriteLine(Encrypt("397854"));
            Console.WriteLine(Encrypt("397786"));
            Console.WriteLine(Encrypt("70001948"));
            Console.WriteLine(Encrypt("70001890"));

            Console.WriteLine("Press enter to close...");
            Console.ReadLine();
        }
    }
}

上面的代码作为控制台应用程序运行时,会产生以下结果,我需要在python3中复制这些结果:

代码语言:javascript
复制
4B7389BB6DFE3AC7
39C739D51AC4FD13
BEB55BBC9430B83583E3E5E4E6C3799E
FD66F55347E715560C963B0EA181FB50

因此,如何使用预定义的密钥和IV?在python3中进行TripleDES加密。

如果您能为我提供任何有用的帮助,我们将不胜感激!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-09-23 19:57:59

基于等于填充,我强烈怀疑您的IV是base64编码的。也许最初的API预期会接收到它base64编码?如果您执行base64.b64decode("AStringOfIV="),它会生成长度为8IV的b'\x01+k\x8ax\x0e|\x85',这可能会得到您想要的行为。

票数 1
EN

Stack Overflow用户

发布于 2020-09-23 21:28:01

确保对每个值使用正确的编码(Base64)和正确的操作模式(CBC)。

这是为我工作的python代码:

代码语言:javascript
复制
import pyDes
import base64

strToEncrypt = "Please encrypt me."
ivStr = "AStringOfIV="
keyStr = "aKeyOfSomeKindThat+IWillNotShare"

k = pyDes.triple_des(
    base64.b64decode(keyStr),
    mode=pyDes.CBC,
    IV=base64.b64decode(ivStr),
    padmode=pyDes.PAD_PKCS5
)
encryptedStr = k.encrypt(strToEncrypt)

k = pyDes.triple_des(
    base64.b64decode(keyStr),
    mode=pyDes.CBC,
    IV=base64.b64decode(ivStr),
    padmode=pyDes.PAD_PKCS5
)
decryptedStr = k.decrypt(encryptedStr)

请注意,由于许多问题,此代码不安全:

  • IV是静态的,但是对于CBC模式必须是不可预测的。静脉输液不应该是秘密的。我们通常在加密期间将其添加到密文中,并在decryption.
  • Triple DES具有小块大小之前将其分割,并且您使用的协议可能容易受到Sweet32或类似的attacks.
  • You're的攻击,而不使用任何类型的身份验证。这样,您将无法检测到在此过程中是否有任何(恶意)更改密文。CBC模式具有一定的可塑性,因此,如果您要将其用于任何严重的操作,则接收方必须验证解密消息,使其完全符合非常严格的结构。相反,我建议使用AES-GCM,或者至少通过加密后的MAC方案添加像HMAC- the 256这样的消息认证代码。
  • 您的C#代码使用默认的操作模式和填充方式。这很棘手,因为在未来的.Net版本中,缺省值可能会改变,这可能会破坏您的代码。始终限定您使用的选项。
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64035325

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档