我想将以下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")
}
答案 0 :(得分:0)
以下是我发现的一些事情,但这个问题有点过于开放:
aesEncryptBase64
中,您手动应用填充。 .NET中的AES实现为您做到了这一点。如果您愿意自己动手,则需要设置aes.Padding = PaddingMode.None
aesEncryptBase64
中,您创建了一个RijndaelManaged
对象。不要这样做。你想要AES,只需使用AES.Create()
,它返回一个AES对象(不是Rijndael对象)。
aesEncryptBase64
aes
ms
,cs
和IDisposable
个对象都是rsaEncrypt
,因此您应该使用它们。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);
}
}
方法正在执行原始RSA,这在.NET中是不受支持的(通常也不是一个好主意)。除非它仅由执行填充的例程调用(然后它只是一个旁道漏洞的坑)。如果你的rsaEncrypt(在Python中)只是从执行签名或加密(或PSS或OAEP)填充的例程调用那么你的.NET等价物就是(使用你的方法命名框,而不是正常的。 NET)
#define KB 1024
#define MB (1024*1024)
size_t poolSize = 16*MB;
尽管如此,改进所有代码将会更好,因此它不必进行如此多的字符串重新解析。