[英]AES / RSA implementation from Python to C#
我想将以下python代码迁移到c#中。 入口点是方法encrypted_request
我在python或c#中没有关于aes / rsa的真正线索。 也许有人可以解释不同的代码部分,并在可能的情况下给我提示如何在c#中实现它。 尤其是在这里和那里使用的魔术数字我不明白。
modulus = ('00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615bb7'
'b725152b3ab17a876aea8a5aa76d2e417629ec4ee341f56135fccf695280'
'104e0312ecbda92557c93870114af6c9d05c4f7f0c3685b7a46bee255932'
'575cce10b424d813cfe4875d3e82047b97ddef52741d546b8e289dc6935b'
'3ece0462db0a22b8e7')
nonce = '0CoJUm6Qyw8W8jud'
pubKey = '010001'
def encrypted_request(text):
text = json.dumps(text)
secKey = createSecretKey(16)
encText = aesEncrypt(aesEncrypt(text, nonce), secKey)
encSecKey = rsaEncrypt(secKey, pubKey, modulus)
data = {'params': encText, 'encSecKey': encSecKey}
return data
def aesEncrypt(text, secKey):
pad = 16 - len(text) % 16
text = text + chr(pad) * pad
encryptor = AES.new(secKey, 2, '0102030405060708')
ciphertext = encryptor.encrypt(text)
ciphertext = base64.b64encode(ciphertext).decode('u8')
return ciphertext
def rsaEncrypt(text, pubKey, modulus):
text = text[::-1]
rs = pow(int(binascii.hexlify(text), 16), int(pubKey, 16)) % int(modulus, 16)
return format(rs, 'x').zfill(256)
def createSecretKey(size):
return binascii.hexlify(os.urandom(size))[:16]
来源: https : //github.com/darknessomi/musicbox/blob/master/NEMbox/api.py
我在C#中的当前状态:
private byte[] hex2Binary(string hex) {
byte[] binaryVal = new byte[hex.Length];
for (int i = 0; i < hex.Length; i++) {
string byteString = hex.Substring(i, 1);
byte b = Convert.ToByte(byteString, 16);
binaryVal[i] = b;
}
return binaryVal;
}
private string aesEncryptBase64(String plainText, string key) {
return aesEncryptBase64(plainText, hex2Binary(key));
}
private string aesEncryptBase64(String plainText, byte[] key) {
//pad = 16 - len(text) % 16
//text = text + chr(pad) * pad
int pad = 16 - plainText.Length % 16;
for (int i=0; i<pad; i++) {
plainText = plainText + ((char)pad);
}
byte[] plainBytes = null;
RijndaelManaged aes = new RijndaelManaged();
//aes.KeySize = 16;
aes.Mode = CipherMode.CBC;
aes.Key = key;
aes.IV = hex2Binary(client.neteaseFix.encryptInfo.iv);
MemoryStream ms = new MemoryStream();
CryptoStream cs = new CryptoStream(ms, aes.CreateEncryptor(), CryptoStreamMode.Write);
cs.Write(plainBytes, 0, plainBytes.Length);
cs.Close();
byte[] encryptedBytes = ms.ToArray();
return Convert.ToBase64String(encryptedBytes); //decode("u8")
}
这是我很快想到的几件事,但问题有点太开放了:
aesEncryptBase64
您正在手动应用填充。 .NET中的AES实现为您完成了此任务。 如果您喜欢自己做,则需要设置aes.Padding = PaddingMode.None
aesEncryptBase64
您将创建一个RijndaelManaged
对象。 不要那样做 您需要AES,只需使用AES.Create()
返回一个AES对象(而不是Rijndael对象)。
aesEncryptBase64
您的aes
, ms
和cs
对象都是IDisposable
,因此应在using语句中使用它们。 rsaEncrypt
方法正在执行原始RSA,.NET不支持该方法(通常也不认为是一个好主意)。 除非仅由执行填充的例程调用(否则,这只是一些旁通道漏洞)。 如果仅从执行签名或加密(或PSS或OAEP)填充的例程中调用rsaEncrypt(在Python中),则等效于.NET(使用方法命名框,而不是.NET中的常规名称)
private static rsaEncrypt(string text, string pubKey, string modulus)
{
RSAParameters rsaParams = new RSAParameters
{
Exponent = hex2Binary(pubKey),
Modulus = hex2Binary(modulus),
};
using (RSA rsa = RSA.Create())
{
rsa.ImportParameters(rsaParams);
return rsa.Encrypt(Encoding.ASCII.GetBytes(text), YOUNEEDTOPICKTHEPADDINGMODE);
}
}
但是,最好围绕它改进所有代码,这样就不必进行太多的字符串重新解析。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.