我在服务器上有一个用RC4算法加密的XML文件(http://rc4crypt.devhome.org)
function encrypt ($pwd, $data, $ispwdHex = 0)
{
if ($ispwdHex)
$pwd = @pack('H*', $pwd); // valid input, please!
$key[] = '';
$box[] = '';
$cipher = '';
$pwd_length = strlen($pwd);
$data_length = strlen($data);
for ($i = 0; $i < 256; $i++)
{
$key[$i] = ord($pwd[$i % $pwd_length]);
$box[$i] = $i;
}
for ($j = $i = 0; $i < 256; $i++)
{
$j = ($j + $box[$i] + $key[$i]) % 256;
$tmp = $box[$i];
$box[$i] = $box[$j];
$box[$j] = $tmp;
}
for ($a = $j = $i = 0; $i < $data_length; $i++)
{
$a = ($a + 1) % 256;
$j = ($j + $box[$a]) % 256;
$tmp = $box[$a];
$box[$a] = $box[$j];
$box[$j] = $tmp;
$k = $box[(($box[$a] + $box[$j]) % 256)];
$cipher .= chr(ord($data[$i]) ^ $k);
}
return $cipher;
}
下面是我用来解密的objective-C代码:
NSData *dataToDecrypt = [NSURLConnection sendSynchronousRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.url.com/fileCrypted.xml"]] returningResponse:nil error:nil];
const void *vplainText;
size_t plainTextBufferSize;
plainTextBufferSize = [dataToDecrypt length];
vplainText = [dataToDecrypt bytes];
CCCryptorStatus ccStatus;
uint8_t *bufferPtr = NULL;
size_t bufferPtrSize = 0;
size_t movedBytes = 0;
bufferPtrSize = (plainTextBufferSize + kCCBlockSize3DES) & ~(kCCBlockSize3DES - 1);
bufferPtr = malloc( bufferPtrSize * sizeof(uint8_t));
memset((void *)bufferPtr, 0x0, bufferPtrSize);
NSString *key = @"mykey";
//NSString *initVec = @"init Vec";
const void *vkey = (const void *) [key UTF8String];
const void *vinitVec = (const void *) [initVec UTF8String];
size_t keyLength = [[key dataUsingEncoding:NSUTF8StringEncoding] length];
ccStatus = CCCrypt(kCCDecrypt,
kCCAlgorithmRC4,
0,
vkey,
kCCKeySizeDES,
nil,
vplainText,
plainTextBufferSize,
(void *)bufferPtr,
bufferPtrSize,
&movedBytes);
if (ccStatus == kCCSuccess) NSLog(@"SUCCESS");
/*else*/ if (ccStatus == kCCParamError) return @"PARAM ERROR";
else if (ccStatus == kCCBufferTooSmall) return @"BUFFER TOO SMALL";
else if (ccStatus == kCCMemoryFailure) return @"MEMORY FAILURE";
else if (ccStatus == kCCAlignmentError) return @"ALIGNMENT";
else if (ccStatus == kCCDecodeError) return @"DECODE ERROR";
else if (ccStatus == kCCUnimplemented) return @"UNIMPLEMENTED";
NSString *result = [[ NSString alloc ] initWithData: [NSData dataWithBytes:(const void *)bufferPtr length:(NSUInteger)movedBytes] encoding:NSASCIIEncoding];
日志输出:成功,但我的结果不好(我测试了许多编码,但ASCII似乎是好的,cf.PHP函数ord…)
我的两个RC4执行标准?
编辑:删除objective-c代码中的iv
edit2:objective-c keylength=密码数据长度,已删除选项
最佳答案
如果你不知道你在密码学中做什么,那么“滚你自己的”无疑是灾难的前兆你不必相信我,阅读john viega onThe Cult of Schneier的文章,了解那些试图“推出自己的”加密技术的普通程序员。别这么做。
因为这是一个文件,而且我猜是一个合理的小文件,所以您可以使用更多的标准和更高级别的库,使用SSL(OpenSSL等)或OpenPGP(GPG等)等标准来进行必要的加密/解密我相信在Objective-C(或iPhone环境)和PHP中都有对SSL的库或模块支持。
尤其是关于rc4,它是一个流密码,看似简单易写,但不可信,很容易混淆其实现细节。参见The Misuse of RC4 in Microsoft Word and Excel和Can you recommend RC4 128-bit encrypted software?了解一个著名的历史性示例,以及安全/密码专家(pgp corp的前首席技术官和联合创始人)的建议。
补充:
php脚本中的keysize基于密码数据的原始长度它也不使用任何PKCS7填充,因此我认为字段应该为零(0)(CCryptor不支持流密码的填充,php版本当然不使用它)在您的代码中,cccrypt使用了8字节(64*位)的密钥大小,而我相信您希望它是密码(二进制数据)的长度(字节)。
数据没有MAC或散列,因此函数将无法从无效的编码中确定有效。
我认为这将使您更接近与rc4(php中的rc4crypt)这个不安全实现的兼容性。
des使用56-bits of key from 64-bits of key input。