开发者

What's the equivalent of C#'s GetBytes() in Python?

I have

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

in a C# AES encryption only class that I'm converting to Python. Can anyone tell me the Python 2.5 equivalent(I'm using this on google app engine?

Example inputs:

request_params: &r=p&playerid=6263017 (or a combination of query strings)

dev_key: GK1FzK12iPYKE9Kt

dev_iv: E2I21NEwsC9RdSN2

dev_id: 12

Python function:

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# Class:

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);
        }
    }
}

Thanks,

Denis


Don't know where you got the following code from

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

but you should know that it is equivalent to the following:

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

which means that non-ASCII characters in any of the three variables will cause an error (I hope you don't make up an AES key of ASCII characters only?).

In Python 2.x, str objects (byte[] in C#) are bytes and unicode objects (string in C#) are for text. This confusing fact was changed in Python 3.x, by the way.
That means if request_params is a Unicode object, you should encode it as UTF-8, and if it's a str object, you should assume (or check) that it is already encoded as UTF-8. So it might be something like:

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

As for key/IV, they will always be binary data (e.g. 16 bytes for AES-128), not text. So they don't have a character encoding. Remove those two lines of code and probably replace them with

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


     buffer = file.read(bytes)
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜