C# 在.net中加密字符串并在python中解密
我正在尝试使用system.Security.Cryptography加密密码,该密码工作正常 这是代码(.Net) 这是python中的解密代码,无法正常工作C# 在.net中加密字符串并在python中解密,c#,asp.net,python-3.x,encryption,cryptography,C#,Asp.net,Python 3.x,Encryption,Cryptography,我正在尝试使用system.Security.Cryptography加密密码,该密码工作正常 这是代码(.Net) 这是python中的解密代码,无法正常工作 def Decryptstr(self, text): try: EncryptionKey = "****" if text is None: return else: cipherbytes = base64.b64decode(
def Decryptstr(self, text):
try:
EncryptionKey = "****"
if text is None:
return
else:
cipherbytes = base64.b64decode(text)
salt = '\0x49\0x76\0x61\0x6e\0x20\0x4d\0x65\0x64\0x76\0x65\0x64\0x65\0x76'
key_bytes = KDF.PBKDF2(EncryptionKey, salt, dkLen=32)
iv = KDF.PBKDF2(EncryptionKey, salt,dkLen=16)
cipher = AES.new(key_bytes, AES.MODE_CBC, iv)
password = cipher.decrypt(cipherbytes).decode('utf-16')
print(password)
return password
except Exception as err:
print(err)
以下是加密字符串(“eet123”)的上述代码的输出
䏺꧴퐄妯軸힡薟
任何帮助都将不胜感激。您的
PBKDF2HMAC
python端的密钥提取似乎不正确。您需要传递正确的参数并获得48字节的密钥。然后将前32个字节用作键
,最后16个字节用作IV
(在您的设计中)
这是一个工作的C#
/Python
代码对。第一部分:
static string encrypt(string clearText = "")
{
if (clearText == null)
{
clearText = "";
}
string EncryptionKey = "****";
byte[] clearBytes = Encoding.UTF8.GetBytes(clearText);
using (Aes encryptor = Aes.Create())
{
Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 }, 100000, HashAlgorithmName.SHA1);
encryptor.Key = pdb.GetBytes(32);
encryptor.IV = pdb.GetBytes(16);
encryptor.Mode = CipherMode.CBC;
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateEncryptor(), CryptoStreamMode.Write))
{
cs.Write(clearBytes, 0, clearBytes.Length);
cs.Close();
}
clearText = Convert.ToBase64String(ms.ToArray());
}
}
return clearText;
}
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
from cryptography.hazmat.backends import default_backend
def Decryptstr(self, text):
try:
if text is None:
return
else:
backend = default_backend()
EncryptionKey = "****"
salt = bytes([ 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 ])
kdf = PBKDF2HMAC(algorithm=hashes.SHA1(),length=48,salt=salt,iterations=100000,backend=backend)
key_parts = kdf.derive(bytes(EncryptionKey, 'utf-8'))
key = key_bytes[0:32]
iv = key_bytes[32:]
cipherbytes = base64.b64decode(text)
cipher = AES.new(key, AES.MODE_CBC, iv)
password = cipher.decrypt(cipherbytes).decode('utf-8')
print(password)
return password
except Exception as err:
print(err)
关于此C#
code:
Rfc2898DeriveBytes
使用SHA1
,并且仅使用1000轮。我的建议是你至少应该使用100000。我见过使用1000000轮的代码应用程序。如果愿意,您也可以更改哈希,但轮数更重要CBC
,但我认为最好指定它C#
使用密钥长度选择AES
算法,因此此代码使用AES-256
李>
现在Python
部分:
static string encrypt(string clearText = "")
{
if (clearText == null)
{
clearText = "";
}
string EncryptionKey = "****";
byte[] clearBytes = Encoding.UTF8.GetBytes(clearText);
using (Aes encryptor = Aes.Create())
{
Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 }, 100000, HashAlgorithmName.SHA1);
encryptor.Key = pdb.GetBytes(32);
encryptor.IV = pdb.GetBytes(16);
encryptor.Mode = CipherMode.CBC;
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateEncryptor(), CryptoStreamMode.Write))
{
cs.Write(clearBytes, 0, clearBytes.Length);
cs.Close();
}
clearText = Convert.ToBase64String(ms.ToArray());
}
}
return clearText;
}
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
from cryptography.hazmat.backends import default_backend
def Decryptstr(self, text):
try:
if text is None:
return
else:
backend = default_backend()
EncryptionKey = "****"
salt = bytes([ 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 ])
kdf = PBKDF2HMAC(algorithm=hashes.SHA1(),length=48,salt=salt,iterations=100000,backend=backend)
key_parts = kdf.derive(bytes(EncryptionKey, 'utf-8'))
key = key_bytes[0:32]
iv = key_bytes[32:]
cipherbytes = base64.b64decode(text)
cipher = AES.new(key, AES.MODE_CBC, iv)
password = cipher.decrypt(cipherbytes).decode('utf-8')
print(password)
return password
except Exception as err:
print(err)
如您所见,我使用了另一个
PBKDF2HMAC
库。我使用它创建了48个字节,并将前32个字节用作键,最后16个字节用作IV
似乎python端的PBKDF2HMAC
键提取不正确。您需要传递正确的参数并获得48字节的密钥。然后将前32个字节用作键
,最后16个字节用作IV
(在您的设计中)
这是一个工作的C#
/Python
代码对。第一部分:
static string encrypt(string clearText = "")
{
if (clearText == null)
{
clearText = "";
}
string EncryptionKey = "****";
byte[] clearBytes = Encoding.UTF8.GetBytes(clearText);
using (Aes encryptor = Aes.Create())
{
Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 }, 100000, HashAlgorithmName.SHA1);
encryptor.Key = pdb.GetBytes(32);
encryptor.IV = pdb.GetBytes(16);
encryptor.Mode = CipherMode.CBC;
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateEncryptor(), CryptoStreamMode.Write))
{
cs.Write(clearBytes, 0, clearBytes.Length);
cs.Close();
}
clearText = Convert.ToBase64String(ms.ToArray());
}
}
return clearText;
}
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
from cryptography.hazmat.backends import default_backend
def Decryptstr(self, text):
try:
if text is None:
return
else:
backend = default_backend()
EncryptionKey = "****"
salt = bytes([ 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 ])
kdf = PBKDF2HMAC(algorithm=hashes.SHA1(),length=48,salt=salt,iterations=100000,backend=backend)
key_parts = kdf.derive(bytes(EncryptionKey, 'utf-8'))
key = key_bytes[0:32]
iv = key_bytes[32:]
cipherbytes = base64.b64decode(text)
cipher = AES.new(key, AES.MODE_CBC, iv)
password = cipher.decrypt(cipherbytes).decode('utf-8')
print(password)
return password
except Exception as err:
print(err)
关于此C#
code:
默认情况下,Rfc2898DeriveBytes
使用SHA1
,并且仅使用1000轮。我的建议是你至少应该使用100000。我见过使用1000000轮的代码应用程序。如果愿意,您也可以更改哈希,但轮数更重要
也指定模式。尽管默认情况下它使用CBC
,但我认为最好指定它
由于C#
使用密钥长度选择AES
算法,因此此代码使用AES-256
李>
现在Python
部分:
static string encrypt(string clearText = "")
{
if (clearText == null)
{
clearText = "";
}
string EncryptionKey = "****";
byte[] clearBytes = Encoding.UTF8.GetBytes(clearText);
using (Aes encryptor = Aes.Create())
{
Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 }, 100000, HashAlgorithmName.SHA1);
encryptor.Key = pdb.GetBytes(32);
encryptor.IV = pdb.GetBytes(16);
encryptor.Mode = CipherMode.CBC;
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateEncryptor(), CryptoStreamMode.Write))
{
cs.Write(clearBytes, 0, clearBytes.Length);
cs.Close();
}
clearText = Convert.ToBase64String(ms.ToArray());
}
}
return clearText;
}
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
from cryptography.hazmat.backends import default_backend
def Decryptstr(self, text):
try:
if text is None:
return
else:
backend = default_backend()
EncryptionKey = "****"
salt = bytes([ 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 ])
kdf = PBKDF2HMAC(algorithm=hashes.SHA1(),length=48,salt=salt,iterations=100000,backend=backend)
key_parts = kdf.derive(bytes(EncryptionKey, 'utf-8'))
key = key_bytes[0:32]
iv = key_bytes[32:]
cipherbytes = base64.b64decode(text)
cipher = AES.new(key, AES.MODE_CBC, iv)
password = cipher.decrypt(cipherbytes).decode('utf-8')
print(password)
return password
except Exception as err:
print(err)
如您所见,我使用了另一个PBKDF2HMAC
库。我用它创建了48个字节,在C#code中,前32个字节作为键,后16个字节作为IV
,您如何告诉Aes
类模式是CBC
?或者默认为CBC
?默认情况下,用于加密的分组密码模式为c#@ikerberaI think.GetBytes()
中的CBC。在这种情况下,C#IV是字节[32:48],而Python IV是字节[0:16](这也是密钥的前半部分!)。另外,我不确定KDF.PBKDF2
中的defult哈希算法是什么,但我认为它与Rfc2898DeriveBytes
(SHA1)相同。KDF.PBKDF2和Rfc2898DeriveBytes@t.m.adam的哈希算法都是相同的。用C编写一个完整的实现,对未加密的文本进行往返。然后用python编写另一个完整的实现,实现同样的功能。尝试将它们分解成小块的功能,在这两个方面做相同的事情。这样一来,a)比较阶段的输出并找出它们不一致的地方要容易得多,b)然后引入一个点,其中一个将数据交给另一个,以满足您的原始需求。在C代码中,您如何告诉Aes
类模式是CBC
?或者默认为CBC
?默认情况下,用于加密的分组密码模式为c#@ikerberaI think.GetBytes()
中的CBC。在这种情况下,C#IV是字节[32:48],而Python IV是字节[0:16](这也是密钥的前半部分!)。另外,我不确定KDF.PBKDF2
中的defult哈希算法是什么,但我认为它与Rfc2898DeriveBytes
(SHA1)相同。KDF.PBKDF2和Rfc2898DeriveBytes@t.m.adam的哈希算法都是相同的。用C编写一个完整的实现,对未加密的文本进行往返。然后用python编写另一个完整的实现,实现同样的功能。尝试将它们分解成小块的功能,在这两个方面做相同的事情。这样一来,a)比较阶段的输出并找出它们不一致的地方会容易得多,b)然后引入一个点,一个点将数据交给另一个点,以满足您的原始需求。您如何使此url安全?如何使此url安全?