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: 12Python 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,
DenisDon'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)
精彩评论