我正在尝试将Objective C TEA加密转换为Javascript,但在其中一个内部循环中,数字与Objective C版本不匹配
这是Objective C版本
#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;
}
我的JavaScript版
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;
}
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);
// prints 167da396 9b183f2e d12ac3f5 5083a581.....
我的版本开始在for(var i=0;i<TIMES;i++)
循环内提供错误的值。然后它在newbyte.writeInt8
部分崩溃。
答案 0 :(得分:1)
最后,我做到了。这是一个正常加密和解密任何文本大小的工作版本。
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
};
```