Python 中 C# 的 GetBytes() 等价物是啥?

Posted

技术标签:

【中文标题】Python 中 C# 的 GetBytes() 等价物是啥?【英文标题】:What's the equivalent of C#'s GetBytes() in Python?Python 中 C# 的 GetBytes() 等价物是什么? 【发布时间】:2010-07-21 07:19:00 【问题描述】:

我有

byte[] request = UTF8Encoding.UTF8.GetBytes(requestParams); 

在我要转换为 Python 的仅 C# AES 加密类中。谁能告诉我 Python 2.5 的等价物(我在谷歌应用引擎上使用它?

示例输入:

request_params: &r=p&playerid=6263017(或查询字符串的组合)dev_key: GK1FzK12iPYKE9Ktdev_iv: E2I21NEwsC9RdSN2dev_id: 12

Python 函数:

def Encrypt(self, request_params, dev_key, dev_iv, dev_id):

    data_bytes = request_params.encode("utf-8")
    block_size = 16
    mode = AES.MODE_CBC
    assert len(dev_key) == block_size and len(dev_iv) == block_size

    pad_char = '0'
    pad_length = block_size - len(data_bytes) % block_size
    padded_data_bytes = data_bytes + pad_length * pad_char

    encrypted_bytes = dev_iv + AES.new(dev_key, mode, dev_iv).encrypt(padded_data_bytes)
    base64_encrypted_string = base64.urlsafe_b64encode(str(encrypted_bytes))
    request_uri = "http://api.blackoutrugby.com/?d=" + dev_id + "&er=" + base64_encrypted_string
    #http://api.blackoutrugby.com/?d=19&er=RTJJNTFORXdzQzNSZFNObNerdsGhiNoeue6c3mzed4Ty1YE-gTlVJVXHz05uPT-8
    # output from this Python code, it's incorrect
    #http://api.blackoutrugby.com/?d=19&er=16t2waGI2h657pzebN53hPr4kEjOzgsOEZiycDwPXR4=
    # correct output from C# code
    return request_uri

C# 类:

using System;
using System.Security.Cryptography;
using System.Text;
using System.IO;
using System.Net;
using System.Xml;
using Newtonsoft.Json;


namespace BlackoutRugbyPOC.Controllers 
    public class BlackoutRugbyAPI 
        public static string Request(string requestParams, string devKey, string devIV, string devID) 
            // Create an unencrypted request as an array of bytes
            byte[] request = UTF8Encoding.UTF8.GetBytes(requestParams);
            byte[] key = UTF8Encoding.UTF8.GetBytes(devKey);
            byte[] iv = UTF8Encoding.UTF8.GetBytes(devIV);

            AesCryptoServiceProvider aes = new AesCryptoServiceProvider();
            aes.Key = key;
            aes.IV = iv;
            aes.Mode = CipherMode.CBC;
            aes.Padding = PaddingMode.Zeros;

            // Get the transformer from the AES Encryptor
            ICryptoTransform cTransform = aes.CreateEncryptor();

            // Use the transformer to encrypt our request
            byte[] result = cTransform.TransformFinalBlock(request, 0, request.Length);
            aes.Clear();

            // Encode to base64
            string encryptedRequest = Convert.ToBase64String(result, 0, result.Length);

            // Send request to API
            string requestUri = "http://api.blackoutrugby.com/?d=" + devID + "&er=" + encryptedRequest;
            string xmlResponse = getWebResponse(requestUri);
            return XmlToJson(xmlResponse);
        

        private static string getWebResponse(string url) 
            string html = "";

            WebRequest request = HttpWebRequest.Create(url);
            WebResponse response = request.GetResponse();

            using (StreamReader reader = new StreamReader(response.GetResponseStream())) 
                html = reader.ReadToEnd();
            
            return html;
        

        public static string XmlToJson(string xml) 
            if (string.IsNullOrEmpty(xml))
                throw new ArgumentNullException("XML Input");

            XmlDocument doc = new XmlDocument();
            try 
                doc.LoadXml(xml);
             catch 
                throw new ArgumentNullException("Input could not be loaded into XML Document");
            

            return JsonConvert.SerializeXmlNode(doc, Newtonsoft.Json.Formatting.Indented);
        
    

谢谢, 丹尼斯

【问题讨论】:

为什么使用字符串作为键/IV?我猜你只使用A-Za-z0-9?!这会将密钥强度降低到 95 位。 BTW PaddingMode.Zeros 指的是二进制零,而不是 Python 代码中的字符“0”。改用 "\x00" 来生成一个值为 0 的二进制字节。 密钥和 IV 由 API 服务 (blackoutrugby.com) 提供,这要求我对发送给它的请求使用 AES How Does One Read Bytes from File in Python 的可能重复项 【参考方案1】:

不知道你从哪里得到以下代码

data_bytes = str.encode(request_params)
key_bytes = str.encode(dev_key)
iv_bytes = str.encode(dev_iv)

但你应该知道它等同于以下内容:

data_bytes = request_params.encode("ascii")
key_bytes = dev_key.encode("ascii")
iv_bytes = dev_iv.encode("ascii")

这意味着这三个变量中的任何一个中的非 ASCII 字符都会导致错误(我希望你不要只用 ASCII 字符组成一个 AES 密钥?)。

在 Python 2.x 中,str 对象(C# 中的byte[])是字节,unicode 对象(C# 中的string)是文本。顺便说一下,这个令人困惑的事实在 Python 3.x 中得到了改变。 这意味着如果request_params 是一个Unicode 对象,你应该将它编码为UTF-8,如果它是一个str 对象,你应该假设(或检查)它已经被编码为UTF-8。所以它可能是这样的:

if isinstance(request_params, unicode):
    data_bytes = request_params.encode("utf-8")
else:
    request_params.decode("utf-8") # optional check whether it is correct UTF-8
    data_bytes = request_params

至于密钥/IV,它们将始终是 二进制 数据(例如 AES-128 的 16 字节),而不是文本。所以他们没有字符编码。删除这两行代码,并可能将它们替换为

assert len(dev_key) == block_size and len(dev_iv) == block_size

【讨论】:

【参考方案2】:
     buffer = file.read(bytes)

【讨论】:

以上是关于Python 中 C# 的 GetBytes() 等价物是啥?的主要内容,如果未能解决你的问题,请参考以下文章

Oracle 12c 等效于 C# Encoding.ASCII.GetBytes

C#:ArgumentNullException:字符串引用未设置为字符串的实例。参数名称:s System.Text.Encoding.GetBytes(string s)

C# byte和10进制16进制相互转换

ASCIIEncoding.ASCII.GetBytes() 返回意外值

C# HmacMD5 加密

c# 将文件gbk转换为utf-8