I'm trying to use symmetric encryption to pass data from actionscript 3 (client) to python (server).
The libraries I'm using are as3crypto and pycrypto, I'm not sure if I'm using these libraries correctly.
Actionscript 3:
private function testOnInit():void {
var t_toEnc:String = 'testtest';
var t_byAry:ByteArray = Hex.toArray( Hex.fromString( t_toEnc ) );
var t_key:ByteArray = Hex.toArray( Hex.fromString( 'Thisisthekey' ) );
var t_cbc:CBCMode = new CBCMode( new BlowFishKey( t_key ), new NullPad );
var t_enc:String;
t_cbc.IV = Hex.toArray( '30313233' );
t_cbc.encrypt( t_byAry );
t_enc = Base64.encodeByteArray( t_byAry );
dbg( 'b64 encrypted string ' + t_enc ); //this is just a debugging function we use in our code.
}
This is the base64 encoded output of the function above.
xvVqLzV5TU4=
Now, using the same key, initialization vector, and algorithm from the pycrypto library gives me different output.
Python:
from Crypto.Cipher import Blowfish
B = Blowfish.new( 'Thisisthekey', Blowfish.MODE_CBC, '30313233' )
S = 'testtest'
X = B.encrypt( S )
import base64
Y = base64.b64encode( X )
print Y
I82NQEkSHhE=
I'm pretty sure that I'm doing something wrong with the encryption process because I can base64 encode 'testtest' on both libraries and receive the same output.
Actionscript 3:
var b:ByteArray = new ByteArray();
b.writeUTFBytes( 'testtest' );
dbg( Base64.encodeByteArray( b ) );
Yields...
dGVzdHRlc3Q=
Python:
>>> T = 'testtest'
>>> print base64.b64encode( T )
Yields
dGVzdHRlc3Q=
Could someone please encrypt and base64encode the same string with the same IV in either python or actionscript, so I know which library is actually producing the correct output?
The problem might be in padding. ActionScript uses no padding, but Py doesn't show what padding it uses. So, it can be the reason. Try another padding (PKCS#5 for instance) with actionscript.
Related
I want to encrypt an exe file (file.exe), write the encrypted version to a text file (fileenc.txt) and decrypt the data in the text file back to another exe file (filedec.exe).
file.exe and filedec.exe are the same and are expected to function the same way.
However, when I try to do this the filedec.exe does not work. Error Popup says: "This app cannot run on your PC".
Please what could be the problem?
However, when I just read the file.exe, write to fileenc.txt without encryption or decryption, and then read fileenc.txt and write data to filedec.exe without encryption or decryption, filedec.exe seems to work fine.
Also, when I try encrypting and decrypting a text file with this code, it works fine too.
But when I encrypt and decrypt an exe on the fly, filedec.exe doesn't work.
Please help me out. Thank you everyone.
Here is my full code:
Main();
function Main() {
var arrKey;
arrKey = "encryptionkey";
//Encrypt file.exe and write the encrypted form to file.txt
Crypt( "C:\\...\\file.exe", "C:\\...\\fileenc.txt", arrKey );
//Decrypt the previously encrypted file.txt and write the decrypted form to filedec.exe
Crypt( "C:\\...\\fileenc.txt", "C:\\...\\filedec.exe", arrKey );
//NOTE: file.exe and filedec.exe are expected to work fine when executed
}
function Crypt(fileIn, fileOut, key) {
var fileInRead;
//Read fileIn
var adTypeBinaryRead = 1;
var BinaryStreamRead;
BinaryStreamRead = new ActiveXObject("ADODB.Stream");
BinaryStreamRead.Type = adTypeBinaryRead;
BinaryStreamRead.Open();
BinaryStreamRead.LoadFromFile(fileIn);
fileInRead = BinaryStreamRead.Read();
//Convert fileIn binary data to string
var objRS = new ActiveXObject("ADODB.Recordset");
var DefinedSize = 1024;
var adSaveCreateOverWrite = 2;
var adFldLong = 0x80;
var adVarChar = 201;
var adTypeText = 2;
objRS.Fields.Append("filedata", adVarChar, DefinedSize, adFldLong);
objRS.Open();
objRS.AddNew();
objRS.Fields("filedata").AppendChunk(fileInRead);
var binString = objRS("filedata").value;
objRS.close();
//Make key as long as string version of fileIn
while (key.length < binString.length) {
key += key;
}
key = key;
//crypt converted string with key
var k, ss, q;
var cryptresult = "";
i = 0;
for (var index = 0; index < binString.length; index++) {
k = key.substr(i, 1);
q = binString.substr(i, 1);
ss = q.charCodeAt(0);
cryptresult = cryptresult + String.fromCharCode(q.charCodeAt(0) ^ k.charCodeAt(0));
i = i +1;
}
// write crypted string to file
var outStreamW = new ActiveXObject("ADODB.Stream");
outStreamW.Type = adTypeText;
// Charset: the default value seems to be `UTF-16` (BOM `0xFFFE` for text files)
outStreamW.Open();
outStreamW.WriteText(cryptresult);
outStreamW.Position = 0;
var outStreamA = new ActiveXObject("ADODB.Stream");
outStreamA.Type = adTypeText;
outStreamA.Charset = "windows-1252"; // important, see `cdoCharset Module Constants`
outStreamA.Open();
outStreamW.CopyTo(outStreamA); // convert encoding
outStreamA.SaveToFile(fileOut, adSaveCreateOverWrite);
outStreamW.Close();
outStreamA.Close();
}
EDIT:
More troubleshooting into my code shows that when I encrypt and decrypt file.exe ON THE FLY, and then write the decrypted data to fileenc.exe, fileenc.exe works well.
But when I encrypt file.exe and write the encrypted data to fileenc.txt and then read the fileenc.txt, decrypt the read encrypted data and write to fileenc.exe (just like in my code), fileenc.exe gets corrupted. My understanding suggests that the manner through which I write the encrypted data to fileenc.txt could be the problem here.
Please I need help, how do I go about with this.
I got a mp4 data using FileReader api, but I have a problem at encoding!
With this function,
var reader = new FileReader();
var blob = new Blob([this.response], {type : "video/mp4"});
reader.onload= function (evt) {
mp4text = evt.target.result;
mp4text = mp4text.toString()
//mp4text = mp4text.slice(22);
//mp4text = CryptoJS.AES.encrypt(mp4text, "test");
//mp4text = window.atob(mp4text);
var myBlob = new Blob([evt.target.result], {type : "video/mp4"});//NOT SAME contrast to blob!
var downloadUrl = URL.createObjectURL(myBlob);
document.getElementById('myVideo').src = downloadUrl;
}
reader.readAsBinaryString(blob);
I thought myBlob has same filedata as blob but some data changed! With more detail, Many of character are same but some hex code is different. How can I solve this problem?
Strings in JavaScript cannot represent arbitrary binary data, so doing readAsBinaryString may not be what you think.
What readAsBinaryString does is for each source byte it gives you a destination character(I don't which character encoding it uses off the top of my head).
So if you have a utf-8 character say ✔, then readAsBinaryString will give you â since that character is tree bytes long %E2%9C%94.
If you try to turn this back to binary/blob the string â is treated as utf-8 which is not 3 bytes but 7(%C3%A2%C5%93%E2%80%9D)
My suggestion would be to use readAsArrayBuffer, I'm sure CryptoJS supports arraybuffers.
What if i only want to process image from disk for reading text from it and storing them in text file.
As it is working for both json and data. i want to do work with data only. How to do that?
from __future__ import print_function
import time
import requests
import cv2
import operator
import numpy as np
# Import library to display results
import matplotlib.pyplot as plt
%matplotlib inline
_url = 'https://api.projectoxford.ai/vision/v1/analyses'
_key = 'd784ea882edd4feaa373dc5a80fa87e8'
_maxNumRetries = 10
def processRequest( json, data, headers, params ):
"""
Helper function to process the request to Project Oxford
Parameters:
json: Used when processing images from its URL. See API Documentation
data: Used when processing image read from disk. See API Documentation
headers: Used to pass the key information and the data type request
"""
retries = 0
result = None
while True:
response = requests.request( 'post', _url, json = json, data = data, headers = headers, params = params )
if response.status_code == 429:
print( "Message: %s" % ( response.json()['error']['message'] ) )
if retries <= _maxNumRetries:
time.sleep(1)
retries += 1
continue
else:
print( 'Error: failed after retrying!' )
break
elif response.status_code == 200 or response.status_code == 201:
if 'content-length' in response.headers and int(response.headers['content-length']) == 0:
result = None
elif 'content-type' in response.headers and isinstance(response.headers['content-type'], str):
if 'application/json' in response.headers['content-type'].lower():
result = response.json() if response.content else None
elif 'image' in response.headers['content-type'].lower():
result = response.content
else:
print( "Error code: %d" % ( response.status_code ) )
print( "Message: %s" % ( response.json()['error']['message'] ) )
break
return result
def renderResultOnImage( result, img ):
"""Display the obtained results onto the input image"""
R = int(result['color']['accentColor'][:2],16)
G = int(result['color']['accentColor'][2:4],16)
B = int(result['color']['accentColor'][4:],16)
cv2.rectangle( img,(0,0), (img.shape[1], img.shape[0]), color = (R,G,B), thickness = 25 )
if 'categories' in result:
categoryName = sorted(result['categories'], key=lambda x: x['score'])[0]['name']
cv2.putText( img, categoryName, (30,70), cv2.FONT_HERSHEY_SIMPLEX, 2, (255,0,0), 3 )
pathToFileInDisk = r'test.jpg'
with open( pathToFileInDisk, 'rb' ) as f:
data = f.read()
# Computer Vision parameters
params = { 'visualFeatures' : 'Color,Categories'}
headers = dict()
headers['Ocp-Apim-Subscription-Key'] = _key
headers['Content-Type'] = 'application/octet-stream'
json = None
result = processRequest( json, data, headers, params )
if result is not None:
# Load the original image, fetched from the URL
data8uint = np.fromstring( data, np.uint8 ) # Convert string to an unsigned int array
img = cv2.cvtColor( cv2.imdecode( data8uint, cv2.IMREAD_COLOR ), cv2.COLOR_BGR2RGB )
renderResultOnImage( result, img )
ig, ax = plt.subplots(figsize=(15, 20))
ax.imshow( img )
It's showing sytax error at %matplot inline
I gather you copied your Python code from somewhere, and there are a number of issues with it:
Your syntax error is stemming from the fact that %matplotlib is valid syntax for iPython, not plain Python.
Based on your problem description, IIUC, you've no need for any plotting code, so you might as well drop matplotlib (and cv2 and numpy, for that matter).
Your API URL is wrong: you want https://api.projectoxford.ai/vision/v1.0/ocr.
The code you'll want will be basically like this:
import json
import requests
import urllib
headers = {
# Request headers
'Content-Type': 'application/json',
'Ocp-Apim-Subscription-Key': 'YOUR_KEY_HERE',
}
params = urllib.urlencode({
# Request parameters
'language': 'unk',
'detectOrientation ': 'true',
})
body = {"url":"YOUR_URL_HERE"}
response = requests.post("https://api.projectoxford.ai/vision/v1.0/ocr?%s" % params, json=body, headers=headers)
result = response.json()
for region in result['regions']:
for line in region['lines']:
for word in line['words']:
print word['text']
Get more details about the response JSON on the API page, if you want, for instance, to arrange the text differently.
You forgot to redact your API key, so you'll probably want to generate a new one via the subscriptions page.
I have this Python script to encrypt/decrypt URLs:
# -*- coding: utf-8 -*-
import base64
from operator import itemgetter
class cryptUrl:
def __init__(self):
self.key = 'secret'
def encode(self, str):
enc = []
for i in range(len(str)):
key_c = self.key[i % len(self.key)]
enc_c = chr((ord(str[i]) + ord(key_c)) % 256)
enc.append(enc_c)
return base64.urlsafe_b64encode("".join(enc))
def decode(self, str):
dec = []
str = base64.urlsafe_b64decode(str)
for i in range(len(str)):
key_c = self.key[i % len(self.key)]
dec_c = chr((256 + ord(str[i]) - ord(key_c)) % 256)
dec.append(dec_c)
return "".join(dec)
url = "http://google.com";
print cryptUrl().encode(url.decode('utf-8'))
This works fine. For example the above url is converted to 29nX4p-joszS4czg2JPG4dI= and the decryption brings it back to the URL.
Now i want to convert this to a PHP function. So far encryption is working fine....but decryption is not....and i dont know why.....so far i got this:
function base64_url_encode($input) {
return strtr(base64_encode($input), '+/=', '-_');
}
function base64_url_decode($input) {
return strtr(base64_decode($input), '-_', '+/=');
}
function encode ($str)
{
$key = 'secret';
$enc = array();
for ($i;$i<strlen($str);$i++){
$key_c = $key[$i % strlen($key)];
$enc_c = chr((ord($str[$i]) + ord($key_c)) % 256);
$enc[] = $enc_c;
}
return base64_url_encode(implode($enc));
}
function decode ($str)
{
$key = 'secret';
$dec = array();
$str = base64_url_decode($str);
for ($i;$i<strlen($str);$i++){
$key_c = $key[$i % strlen($key)];
$dec_c = chr((256 + ord($str[$i]) + ord($key_c)) % 256);
$dec[] = $dec_c;
}
return implode($dec);
}
$str = '29nX4p-joszS4czg2JPG4dI=';
echo decode($str);
Now the above decoding prints out : N>:Tý\&™åª—Væ which is not http://google.com :p
Like i said encoding function works though.
Why isnt the decoding working ? What am i missing ?
Btw i cant use any other encoding/decoding function. I have a list of URLs encoded with python and i want to move the whole system to a PHP based site....so i need to decode those URLs with a PHP function instead of python.
(Use this page to execute Python: http://www.compileonline.com/execute_python_online.php)
Double check the syntax of strtr().
I'd suggest you using in in the following way:
strtr(
base64_encode($input),
array(
'+' => '-',
'/' => '_',
'=' => YOUR_REPLACE_CHARACTER
)
)
Make sure you have YOUR_REPLACE_CHARACTER!
Also, I'm sure you'll handle the reverse function, where you need to simply flip the values of the replace array.
I was using as3Crypto with no probs
http://www.zedia.net/2009/as3crypto-and-php-what-a-fun-ride/
but then I saw some special characters and I realised I could encounter ampersands.
Which is a pain because they will be inserted into a query string.
Is there a way to ensure the as3Crypto encryption does not produce ampersands?
public function encrypt(txt:String = ''):String
{
var data:ByteArray = Hex.toArray(Hex.fromString(txt));
var pad:IPad = new PKCS5;
var mode:ICipher = Crypto.getCipher(type, key, pad);
pad.setBlockSize(mode.getBlockSize());
mode.encrypt(data);
return ''+Base64.encodeByteArray(data);
}
Assuming a standard base64 implementation, Base64.encodeByteArray(data); will not produce ampersands.