Javascript中的TEA加密 [英] TEA Encryption in Javascript
问题描述
我正在尝试将Objective C TEA加密转换为Javascript,但在其中一个内部循环中,数字与Objective C版本不匹配
这是目标C版本
#define TIMES 32
@implementation NSData(NSData_extend)
//使用pwdKey加密NSData
- (NSData *)addTEA:(const unsigned int *)pwdkey
{
unsigned char * ch =(unsigned char *)[self bytes];
int n = 8-self.length%8;
char byte [self.length + n];
char cc = n;
for(int i = 0; i< n; i ++){
if(i == 0){
byte [i] = cc;
}
else {
byte [i] = 0;
}
}
for(int i = 0; i< self.length; i ++){
byte [n + i] = ch [i];
}
int delta = 0x9e3779b9;
int a = pwdkey [0];
int b = pwdkey [1];
int c = pwdkey [2];
int d = pwdkey [3];
unsigned char newbyte [self.length + n];
for(int offset = 0; offset< self.length + n; offset + = 8){
int y = [self ByteTounint:byte [offset + 3]] | [self ByteTounint:byte [offset + 2]]<< 8 | [self ByteTounint:byte [offset + 1]]<< 16 | [self ByteTounint:byte [offset + 0]]<< 24;
int z = [self ByteTounint:byte [offset + 7]] | [self ByteTounint:byte [offset + 6]]<< 8 | [self ByteTounint:byte [offset + 5]]<< 16 | [self ByteTounint:byte [offset + 4]]<< 24;
int sum = 0;
for(int i = 0; i< TIMES; i ++){
sum + = delta;
y + =((z << 4)+ a)^(z + sum)^((z>> 5)+ b);
z + =((y << 4)+ c)^(y + sum)^((y>> 5)+ d);
}
newbyte [offset + 7] = z& 0x000000ff;
newbyte [offset + 6] =(z& 0x0000ff00)>> 8;
newbyte [offset + 5] =(z& 0x00ff0000)>> 16;
newbyte [offset + 4] =(z& 0xff000000)>> 24;
newbyte [offset + 3] = y& 0x000000ff;
newbyte [offset + 2] =(y& 0x0000ff00)>> 8;
newbyte [offset + 1] =(y& 0x00ff0000)>> 16;
newbyte [offset + 0] =(y& 0xff000000)>> 24;
}
NSData * resultData = [NSData dataWithBytes:newbyte length:self.length + n];
返回resultData;
}
//使用pwdKey解密NSData
- (NSData *)subtractTEA:(const unsigned int *)pwdkey
{
unsigned char * byte =(unsigned char *)[self bytes];
int delta = 0x9e3779b9;
int a = pwdkey [0];
int b = pwdkey [1];
int c = pwdkey [2];
int d = pwdkey [3];
unsigned char newbyte [self.length];
for(int offset = 0; offset< self.length; offset + = 8){
int y = [self ByteTounint:byte [offset + 3]] | [self ByteTounint:byte [offset + 2]]<< 8 | [self ByteTounint:byte [offset + 1]]<< 16 | [self ByteTounint:byte [offset + 0]]<< 24;
int z = [self ByteTounint:byte [offset + 7]] | [self ByteTounint:byte [offset + 6]]<< 8 | [self ByteTounint:byte [offset + 5]]<< 16 | [self ByteTounint:byte [offset + 4]]<< 24;
int sum = 0;
if(TIMES == 32){
sum = 0xC6EF3720;
}
else if(TIMES == 16){
sum = 0xE3779B90;
}
else {
sum = delta * TIMES;
}
for(int i = 0; i< TIMES; i ++){
z - =((y << 4)+ c)^(y + sum) ^((y>>> 5)+ d);
y - =((z << 4)+ a)^(z + sum)^((z>> 5)+ b);
sum - = delta;
}
newbyte [offset + 7] = z& 0x000000ff;
newbyte [offset + 6] =(z& 0x0000ff00)>> 8;
newbyte [offset + 5] =(z& 0x00ff0000)>> 16;
newbyte [offset + 4] =(z& 0xff000000)>> 24;
newbyte [offset + 3] = y& 0x000000ff;
newbyte [offset + 2] =(y& 0x0000ff00)>> 8;
newbyte [offset + 1] =(y& 0x00ff0000)>> 16;
newbyte [offset + 0] =(y& 0xff000000)>> 24;
}
int n = newbyte [0];
unsigned char ch [self.length-n];
for(int i = 0; i< self.length-n; i ++){
ch [i] = newbyte [i + n];
}
NSData * resultData = [NSData dataWithBytes:ch length:self.length -n];
返回resultData;
}
- (int)ByteTounint:(int)byte
{
if(byte< 0){
return(byte + 256);
}
返回字节;
}
我的JavaScript版
< pre class =lang-js prettyprint-override>
TEA.prototype.encrypt = function(src,pwdkey){
var TIMES = 32;
var n = 8 - (src.length%8);
var byte = Buffer.alloc(src.length + n);
var cc = n;
for(var i = 0; i< n; i ++){
if(i == 0){
byte [i] = cc;
}
else {
byte [i] = 0;
}
}
for(var j = 0; j< src.length; j ++){
byte.write(src [j],(n + J));
}
var delta = 0x9e3779b9;
var a = pwdkey.readInt32LE(0);
var b = pwdkey.readInt32LE(1);
var c = pwdkey.readInt32LE(2);
var d = pwdkey.readInt32LE(3);
var newbyte = Buffer.alloc(src.length + n);
for(var offset = 0; offset< src.length + n; offset + = 8){
var y = ByteTounint(byte [offset + 3])| ByteTounint(byte [offset + 2]<< 8)| ByteTounint(byte [offset + 1]<< 16)| ByteTounint(byte [offset + 0])<< 24;
var z = ByteTounint(byte [offset + 7])| ByteTounint(byte [offset + 6])<< 8 | ByteTounint(byte [offset + 5])<< 16 | ByteTounint(byte [offset + 4])<< 24;
var sum = 0;
for(var i = 0; i< TIMES; i ++)
{
sum + = delta;
sum>>> = 0;
y + =(((z << 4)+ a)^(z + sum)^((z>>>> 5)+ b))>>> 0;
z + =(((y << 4)+ c)^(y + sum)^((y>>>> 5)+ d))>>> 0;
}
newbyte.writeInt8((z& 0x000000ff),(offset + 7));
newbyte.writeInt8(((z& 0x0000ff00)>> 8),(offset + 6));
newbyte.writeInt8(((z& 0x00ff0000)>> 16),(offset + 5));
newbyte.writeInt8(((z& 0xff000000)>> 24),(offset + 4));
newbyte.writeInt8((y& 0x000000ff),(offset + 3));
newbyte.writeInt8(((y& 0x0000ff00)>> 8),(offset + 2));
newbyte.writeInt8(((y& 0x00ff0000)>> 16),(offset + 1));
newbyte.writeInt8(((y& 0xff000000)>> 24),(offset + 0));
}
返回newbyte
};
函数ByteTounint(byte){
if(byte< 0){
return(byte + 256);
}
返回字节;
}
JavaScript版本的使用
var pwdkey = new Buffer(4523F10F214365873248738902EFCDAB,hex);
var dene = tea.encrypt(params = {\method \:\waybill.querywaybill \,\requstParams\:{\memNo \: \ \,\ waybillNo\:\ 606447740110\}},pwdkey);
目标版本的用法和样本结果
NSString * keyString = @4523F10F214365873248738902EFCDAB;
NSData * keyData = [NSData dataWithHexString:keyString];
const unsigned char * src =(const unsigned char *)[key bytes];
NSString * str = @params = {\method \:\waybill.querywaybill \,\requstParams\:{\memNo \:\ \,\ waybillNo\:\ 606447740110\}};
NSData * data = [NSData dataWithBytes:str.UTF8String length:str.length];
NSData * result2 = [data addTEA:src];
NSLog(@%@,result2);
//打印167da396 9b183f2e d12ac3f5 5083a581 .....
我的版本开始给出中的错误值为(var i = 0; i< TIMES; i ++)
循环。然后它在 newbyte.writeInt8
部分崩溃。
最后,我使它工作。这是一个正常加密和解密任何文本大小的工作版本。
function ByteTounint(byte){
if(byte< 0){
return(byte + 256);
}
返回字节;
}
TEA.prototype.decrypt = function(src,pwdkey){
var TIMES = 32;
var delta = 0x9e3779b9;
var a = pwdkey.readUInt32LE(0);
var b = pwdkey.readUInt32LE(4);
var c = pwdkey.readUInt32LE(8);
var d = pwdkey.readUInt32LE(12);
var newbyte = Buffer.alloc(src.length);
for(var offset = 0; offset< src.length; offset + = 8){
var y = ByteTounint(src [offset + 3])| ByteTounint(src [offset + 2])<< 8 | ByteTounint(src [offset + 1])<< 16 | ByteTounint(src [offset + 0])<< 24;
var z = ByteTounint(src [offset + 7])| ByteTounint(src [offset + 6])<< 8 | ByteTounint(src [offset + 5])<< 16 | ByteTounint(src [offset + 4])<< 24;
var sum = 0;
if(TIMES == 32){
sum = 0xC6EF3720;
}
else if(TIMES == 16){
sum = 0xE3779B90;
}
else {
sum = delta * TIMES;
}
for(var i = 0; i< TIMES; i ++){
z =(z - ((((y << 4)+ c)& ; 0xFFFFFFFF)^((y + sum)& 0xFFFFFFFF)^(((y>> 5)+ d)& 0xFFFFFFFF)))& 0xFFFFFFFF
y =(y - ((((z << 4)+ a)& 0xFFFFFFFF)^((z + sum)& 0xFFFFFFFF)^(((z>> 5)+ b )& 0xFFFFFFFF)))& 0xFFFFFFFF
sum =(sum-delta)& 0xFFFFFFFF的;
}
newbyte.writeInt32BE((y& 0xFFFFFFFF),offset);
newbyte.writeInt32BE((z& 0xFFFFFFFF),(offset + 4));
}
var n = newbyte [0];
var ch = Buffer.alloc(src.length - n);
for(var i = 0; i< src.length-n; i ++){
ch [i] = newbyte [i + n];
}
返回ch;
};
TEA.prototype.encrypt = function(src,pwdkey){
var TIMES = 32;
var n = 8 - (src.length%8);
var byte = Buffer.alloc(src.length + n);
var cc = n;
for(var i = 0; i< n; i ++){
if(i == 0){
byte [i] = cc;
}
else {
byte [i] = 0;
}
}
for(var j = 0; j< src.length; j ++){
byte.write(src [j ],第(n + j)的);
}
var delta = 0x9e3779b9;
var a = pwdkey.readUInt32LE(0);
var b = pwdkey.readUInt32LE(4);
var c = pwdkey.readUInt32LE(8);
var d = pwdkey.readUInt32LE(12);
var newbyte = Buffer.alloc(src.length + n);
for(var offset = 0; offset< src.length + n; offset + = 8){
var y = ByteTounint(byte [offset + 3]) | ByteTounint(byte [offset + 2])<< 8 | ByteTounint(byte [offset + 1])<< 16 | ByteTounint(byte [offset + 0])<< 24;
var z = ByteTounint(byte [offset + 7])| ByteTounint(byte [offset + 6])<< 8 | ByteTounint(byte [offset + 5])<< 16 | ByteTounint(byte [offset + 4])<< 24;
var sum = 0;
for(var i = 0; i< TIMES; i ++)
{
sum =(sum + delta)& 0xFFFFFFFF的;
y =(y +((((z << 4)+ a)& 0xFFFFFFFF)^((z + sum)& 0xFFFFFFFF)^(((z>> 5)+ b) & 0xFFFFFFFF)))& 0xFFFFFFFF的;
z =(z +((((y << 4)+ c)& 0xFFFFFFFF)^((y + sum)& 0xFFFFFFFF)^(((y>> 5)+ d) & 0xFFFFFFFF)))& 0xFFFFFFFF
}
newbyte.writeInt32BE((y& 0xFFFFFFFF),offset);
newbyte.writeInt32BE((z& 0xFFFFFFFF),(offset + 4));
}
返回newbyte
};
```
I am trying to convert Objective C TEA encryption to Javascript but inside one of the inner loops, numbers doesn't match against Objective C version
Here is the Objective C version
#define TIMES 32
@implementation NSData (NSData_extend)
// Encrypt NSData with pwdKey
-(NSData*)addTEA:(const unsigned int *)pwdkey
{
unsigned char * ch = (unsigned char*)[self bytes];
int n = 8-self.length%8;
char byte[self.length+n];
char cc = n;
for (int i=0; i<n; i++) {
if (i==0) {
byte[i] = cc;
}
else{
byte[i] = 0;
}
}
for (int i=0; i<self.length; i++) {
byte[n+i] = ch[i];
}
int delta = 0x9e3779b9;
int a = pwdkey[0];
int b = pwdkey[1];
int c = pwdkey[2];
int d = pwdkey[3];
unsigned char newbyte[self.length+n];
for (int offset=0; offset<self.length+n; offset += 8) {
int y = [self ByteTounint:byte[offset+3]] | [self ByteTounint:byte[offset+2]]<<8 | [self ByteTounint:byte[offset+1]]<<16 | [self ByteTounint:byte[offset+0]]<<24;
int z = [self ByteTounint:byte[offset+7]] | [self ByteTounint:byte[offset+6]]<<8 | [self ByteTounint:byte[offset+5]]<<16 | [self ByteTounint:byte[offset+4]]<<24;
int sum = 0;
for (int i=0; i<TIMES; i++) {
sum += delta;
y += ((z<<4) + a) ^ (z + sum) ^ ((z>>5) + b);
z += ((y<<4) + c) ^ (y + sum) ^ ((y>>5) + d);
}
newbyte[offset+7] = z & 0x000000ff;
newbyte[offset+6] = (z & 0x0000ff00) >> 8;
newbyte[offset+5] = (z & 0x00ff0000) >> 16;
newbyte[offset+4] = (z & 0xff000000) >> 24;
newbyte[offset+3] = y & 0x000000ff;
newbyte[offset+2] = (y & 0x0000ff00) >> 8;
newbyte[offset+1] = (y & 0x00ff0000) >> 16;
newbyte[offset+0] = (y & 0xff000000) >> 24;
}
NSData * resultData = [NSData dataWithBytes:newbyte length:self.length+n];
return resultData;
}
// Decrypt NSData with pwdKey
-(NSData*)subtractTEA:(const unsigned int *)pwdkey
{
unsigned char * byte = (unsigned char*)[self bytes];
int delta = 0x9e3779b9;
int a = pwdkey[0];
int b = pwdkey[1];
int c = pwdkey[2];
int d = pwdkey[3];
unsigned char newbyte[self.length];
for (int offset=0; offset<self.length; offset += 8) {
int y = [self ByteTounint:byte[offset+3]] | [self ByteTounint:byte[offset+2]]<<8 | [self ByteTounint:byte[offset+1]]<<16 | [self ByteTounint:byte[offset+0]]<<24;
int z = [self ByteTounint:byte[offset+7]] | [self ByteTounint:byte[offset+6]]<<8 | [self ByteTounint:byte[offset+5]]<<16 | [self ByteTounint:byte[offset+4]]<<24;
int sum = 0;
if (TIMES == 32) {
sum = 0xC6EF3720;
}
else if (TIMES == 16){
sum = 0xE3779B90;
}
else{
sum = delta * TIMES;
}
for (int i=0; i<TIMES; i++) {
z -= ((y<<4) + c) ^ (y + sum) ^ ((y>>5) + d);
y -= ((z<<4) + a) ^ (z + sum) ^ ((z>>5) + b);
sum -= delta;
}
newbyte[offset+7] = z & 0x000000ff;
newbyte[offset+6] = (z & 0x0000ff00) >> 8;
newbyte[offset+5] = (z & 0x00ff0000) >> 16;
newbyte[offset+4] = (z & 0xff000000) >> 24;
newbyte[offset+3] = y & 0x000000ff;
newbyte[offset+2] = (y & 0x0000ff00) >> 8;
newbyte[offset+1] = (y & 0x00ff0000) >> 16;
newbyte[offset+0] = (y & 0xff000000) >> 24;
}
int n = newbyte[0];
unsigned char ch[self.length-n];
for (int i=0; i<self.length-n; i++) {
ch[i] = newbyte[i+n];
}
NSData * resultData = [NSData dataWithBytes:ch length:self.length-n];
return resultData;
}
- (int)ByteTounint:(int)byte
{
if (byte<0) {
return (byte+256);
}
return byte;
}
My JavaScript version
TEA.prototype.encrypt = function(src,pwdkey) {
var TIMES = 32;
var n = 8 - (src.length % 8);
var byte = Buffer.alloc(src.length + n);
var cc = n;
for (var i = 0; i < n; i++) {
if (i == 0) {
byte[i] = cc;
}
else {
byte[i] = 0;
}
}
for (var j = 0; j < src.length; j++) {
byte.write( src[j],(n+j));
}
var delta = 0x9e3779b9;
var a = pwdkey.readInt32LE(0);
var b = pwdkey.readInt32LE(1);
var c = pwdkey.readInt32LE(2);
var d = pwdkey.readInt32LE(3);
var newbyte = Buffer.alloc(src.length + n);
for (var offset = 0; offset < src.length + n; offset += 8) {
var y = ByteTounint(byte[offset + 3]) | ByteTounint(byte[offset + 2] << 8) | ByteTounint(byte[offset + 1] << 16) | ByteTounint(byte[offset + 0]) << 24;
var z = ByteTounint(byte[offset + 7]) | ByteTounint(byte[offset + 6]) << 8 | ByteTounint(byte[offset + 5]) << 16 | ByteTounint(byte[offset + 4]) << 24;
var sum = 0;
for(var i=0;i<TIMES;i++)
{
sum += delta;
sum >>>= 0;
y += (((z<<4)+a) ^ (z+sum) ^ ((z>>>5)+b)) >>> 0;
z += (((y<<4)+c) ^ (y+sum) ^ ((y>>>5)+d)) >>> 0;
}
newbyte.writeInt8((z & 0x000000ff),(offset + 7));
newbyte.writeInt8(((z & 0x0000ff00) >> 8),(offset + 6));
newbyte.writeInt8(((z & 0x00ff0000) >> 16),(offset + 5));
newbyte.writeInt8(((z & 0xff000000) >> 24),(offset + 4));
newbyte.writeInt8((y & 0x000000ff),(offset + 3));
newbyte.writeInt8(((y & 0x0000ff00) >> 8),(offset + 2));
newbyte.writeInt8(((y & 0x00ff0000) >> 16),(offset + 1));
newbyte.writeInt8(((y & 0xff000000) >> 24),(offset + 0));
}
return newbyte
};
function ByteTounint(byte) {
if (byte<0) {
return (byte+256);
}
return byte;
}
Usage for JavaScript Version
var pwdkey = new Buffer("4523F10F214365873248738902EFCDAB","hex");
var dene = tea.encrypt("params={\"method\":\"waybill.querywaybill\",\"requstParams\":{\"memNo\":\"\",\"waybillNo\":\"606447740110\"}}",pwdkey);
Usage and Sample Result from Objective version
NSString *keyString = @"4523F10F214365873248738902EFCDAB";
NSData *keyData = [NSData dataWithHexString:keyString];
const unsigned char *src = (const unsigned char *)[key bytes];
NSString *str = @"params={\"method\":\"waybill.querywaybill\",\"requstParams\":{\"memNo\":\"\",\"waybillNo\":\"606447740110\"}}";
NSData *data = [NSData dataWithBytes:str.UTF8String length:str.length];
NSData * result2 = [data addTEA:src];
NSLog(@"%@",result2);
// prints 167da396 9b183f2e d12ac3f5 5083a581.....
My version starts to give wrong values inside for(var i=0;i<TIMES;i++)
loop. Then it crashes during newbyte.writeInt8
part.
Finally, I made it work. Here is a working version which correctly encrypts and decrypts any size of text.
function ByteTounint(byte) {
if (byte<0) {
return (byte+256);
}
return byte;
}
TEA.prototype.decrypt = function(src,pwdkey) {
var TIMES = 32;
var delta = 0x9e3779b9;
var a = pwdkey.readUInt32LE(0);
var b = pwdkey.readUInt32LE(4);
var c = pwdkey.readUInt32LE(8);
var d = pwdkey.readUInt32LE(12);
var newbyte = Buffer.alloc(src.length);
for (var offset=0; offset<src.length; offset += 8) {
var y = ByteTounint(src[offset + 3]) | ByteTounint(src[offset + 2]) << 8 | ByteTounint(src[offset + 1]) << 16 | ByteTounint(src[offset + 0]) << 24;
var z = ByteTounint(src[offset + 7]) | ByteTounint(src[offset + 6]) << 8 | ByteTounint(src[offset + 5]) << 16 | ByteTounint(src[offset + 4]) << 24;
var sum = 0;
if (TIMES == 32) {
sum = 0xC6EF3720;
}
else if (TIMES == 16) {
sum = 0xE3779B90;
}
else {
sum = delta * TIMES;
}
for (var i = 0; i < TIMES; i++) {
z = (z - (( ( (y<<4) + c) & 0xFFFFFFFF) ^ ( (y + sum) & 0xFFFFFFFF ) ^ ( ((y >> 5) + d ) & 0xFFFFFFFF))) & 0xFFFFFFFF
y = (y - (( ( (z<<4) + a) & 0xFFFFFFFF) ^ ( (z + sum) & 0xFFFFFFFF ) ^ ( ((z >> 5) + b ) & 0xFFFFFFFF))) & 0xFFFFFFFF
sum = (sum - delta) & 0xFFFFFFFF;
}
newbyte.writeInt32BE((y & 0xFFFFFFFF),offset);
newbyte.writeInt32BE((z & 0xFFFFFFFF),(offset+4));
}
var n = newbyte[0];
var ch = Buffer.alloc(src.length - n);
for (var i=0; i<src.length-n; i++) {
ch[i] = newbyte[i+n];
}
return ch;
};
TEA.prototype.encrypt = function(src,pwdkey) {
var TIMES = 32;
var n = 8 - (src.length % 8);
var byte = Buffer.alloc(src.length + n);
var cc = n;
for (var i = 0; i < n; i++) {
if (i == 0) {
byte[i] = cc;
}
else {
byte[i] = 0;
}
}
for (var j = 0; j < src.length; j++) {
byte.write( src[j],(n+j));
}
var delta = 0x9e3779b9;
var a = pwdkey.readUInt32LE(0);
var b = pwdkey.readUInt32LE(4);
var c = pwdkey.readUInt32LE(8);
var d = pwdkey.readUInt32LE(12);
var newbyte = Buffer.alloc(src.length + n);
for (var offset = 0; offset < src.length + n; offset += 8) {
var y = ByteTounint(byte[offset + 3]) | ByteTounint(byte[offset + 2]) << 8 | ByteTounint(byte[offset + 1]) << 16 | ByteTounint(byte[offset + 0]) << 24;
var z = ByteTounint(byte[offset + 7]) | ByteTounint(byte[offset + 6]) << 8 | ByteTounint(byte[offset + 5]) << 16 | ByteTounint(byte[offset + 4]) << 24;
var sum = 0;
for(var i=0;i<TIMES;i++)
{
sum = (sum + delta) & 0xFFFFFFFF;
y = (y + (( ( (z<<4) + a) & 0xFFFFFFFF) ^ ( (z + sum) & 0xFFFFFFFF ) ^ ( ((z >> 5) + b ) & 0xFFFFFFFF))) & 0xFFFFFFFF;
z = (z + (( ( (y<<4) + c) & 0xFFFFFFFF) ^ ( (y + sum) & 0xFFFFFFFF ) ^ ( ((y >> 5) + d ) & 0xFFFFFFFF))) & 0xFFFFFFFF
}
newbyte.writeInt32BE((y & 0xFFFFFFFF),offset);
newbyte.writeInt32BE((z & 0xFFFFFFFF),(offset+4));
}
return newbyte
};
```
这篇关于Javascript中的TEA加密的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!