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



由于遗留的C#.NET代码,我无法更改键和IV。但我似乎找不到一种方法来做我需要做的事情。我试过这个。。。

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字节">

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

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((检查它,如上所示,只是想看看会发生什么:

ivStr = "AStringOfIV===="

我收到了同样的信息,";无效的初始值(IV(必须是8字节的倍数;。但是是的。现在怎么办?

我试着直接将其作为字节传递,既有原始的ivStr,也有64字节的,带有额外的等号。

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,如下所示:

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代码(在这里:

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:中复制这些结果

4B7389BB6DFE3AC7
39C739D51AC4FD13
BEB55BBC9430B83583E3E5E4E6C3799E
FD66F55347E715560C963B0EA181FB50

那么,我如何使用预定义的密钥和IV在python3中进行TripleDES加密

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

基于等号填充,我强烈怀疑您的IV是base64编码的。也许最初的API期望接收它base64编码?如果你做base64.b64decode("AStringOfIV="),它会产生一个长度为8IV的b'x01+kx8axx0e|x85',它可能会得到你想要的行为。

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

这是适用于我的python代码:

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模式必须是不可预测的。静脉注射不应该是秘密。我们通常在加密过程中将其预处理到密文中,并在解密前将其切片
  • Triple DES的块大小很小,您使用的协议可能容易受到Sweet32或类似攻击
  • 您没有使用任何类型的身份验证。这样,您将无法检测到在加密过程中是否有任何(恶意(更改。CBC模式是部分可延展的,所以如果您将其用于任何严重的事情,接收器必须验证解密的消息,使其完全符合非常严格的结构。相反,我建议使用AES-GCM,或者至少通过先加密后MAC的方案添加像HMAC-SHA256这样的消息验证码
  • 您的C#代码使用默认的操作模式和填充。这很棘手,因为默认值可能会在未来的.Net版本中更改,这可能会破坏您的代码。请务必确定您正在使用的选项

最新更新