最近一直在解决RSA加密方面的,看了网上不少教程。大部分都是基于.cer文件进行加密的,而在我们的项目中服务器端只返回两个值分别是mod和exp。经过分析对比数据,发现实际上.cer文件就是由这两个数据组合得到的。文件格式如下:
0x30 包长 { 0x02 包长 { mod 0x02 包长 { exp } } }
包长用来记录后面大括号表示的包占用字节数 len
在cer文件中,包长由1-3个字节组成:
- 当包长小于128位时长度为1,该字节值等于 len
- 128-255之间长度为2, 分别为 0x81 , len
- 大于255长度为3,分别为 0x82 ,len>>8 , len
(理论上大于65535时应为4,未验证该结果)
代码如下
-(NSData *)cerWithMod:(NSData *)modBits exp:(NSData *)expBits{
if(!(mod && exp)){
@throw [NSException exceptionWithName:@"NSInvalidArgumentException" reason:@"Data not set." userInfo:nil];
}
//整个证书分为8个部分
//创建证书存储空间,其中第二第四部分包长按照1byte处理
NSMutableData *fullKey = [[NSMutableData alloc] initWithLength:6+[modBits length]+[expBits length]];
unsigned char *fullKeyBytes = [fullKey mutableBytes];
unsigned int bytep = 0; // current byte pointer
/**
* 0x30 包长 { 0x02 包长 { modBits 0x02 包长 { expBits } } }
*/
//第一部分:(1 byte)固定位0x30
fullKeyBytes[bytep++] = 0x30;
//第二部分:(1-3 byte)记录包长
unsigned int ml = 4+[modBits length]+[expBits length];
if (ml >= 256)
{
//当长度大于256时占用 3 byte
fullKeyBytes[bytep++] = 0x82;
fullKeyBytes[bytep++] = ml >> 8;
[fullKey increaseLengthBy:2];
}else if(ml >= 128)
{
//当长度大于128时占用 2 byte
fullKeyBytes[bytep++] = 0x81 ;
[fullKey increaseLengthBy:1];
}
//处理最后一个 byte
unsigned int seqLenLoc = bytep;
fullKeyBytes[bytep++] = 4+[modBits length]+[expBits length];
//第三部分 (1 byte)固定位0x02
fullKeyBytes[bytep++] = 0x02;
//第四部分:(1-3 byte)记录包长
ml = [modBits length];
if (ml >= 256)
{
//当长度大于256时占用 3 byte
fullKeyBytes[bytep++] = 0x82;
//第二部分包长+1
fullKeyBytes[seqLenLoc] += 2;
fullKeyBytes[bytep++] = ml >> 8;
[fullKey increaseLengthBy:2];
}else if(ml >= 128){
//当长度大于256时占用 2 byte
fullKeyBytes[bytep++] = 0x81 ;
//第二部分包长+2
fullKeyBytes[seqLenLoc]++;
[fullKey increaseLengthBy:1];
}
//处理最后一个 byte
fullKeyBytes[bytep++] = [modBits length];
//第五部分
[modBits getBytes:&fullKeyBytes[bytep]];
bytep += [modBits length];
//第六部分
fullKeyBytes[bytep++] = 0x02;
//第七部分
fullKeyBytes[bytep++] = [expBits length];
//第八部分
[expBits getBytes:&fullKeyBytes[bytep++]];
return fullKey;
}