直接上代码。。。
/*按行读取一个pem文件所有字符并拼接为一整个字符串返回,去除首行、尾行及换行符*/
char* LoadPemFile(char* pemFilePath,int* length)
{
FILE* file;
size_t size = 0;
char* buff;
file = fopen(pemFilePath,"rb");
if(file==NULL)
{
return NULL;
}
fseek(file,0L,SEEK_END); /*定位至文件尾*/
size = ftell(file); /*获取文件大小*/
buff = (char*)malloc(size);
fseek(file,0L,SEEK_SET); /*定位至文件首*/
size = 0;
char line[1024]; //假设单行最长不超过1024,pem文件单行不会超过此限制
while (!feof(file) && !ferror(file))
{
memset(line,0,sizeof(line));
fgets(line, sizeof(line), file);
int len=strlen(line);
line[len-1]=0;//为了去除行尾的\n
if(line[0]!='-') //去除首行和尾行
{
memcpy(buff+size,line,strlen(line));
size += strlen(line);
}
}
fclose(file);
*length = size;
//printf("%s",buff);
return buff;
}
/*解码Base64,参数bindata需预先分配足够内存。返回值为解码后的实际长度*/
int base64_decode( const char * base64, unsigned char * bindata )
{
int i, j;
unsigned char k;
unsigned char temp[4];
const char * base64char = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
for ( i = 0, j = 0; base64[i] != '\0' ; i += 4 )
{
memset( temp, 0xFF, sizeof(temp) );
for ( k = 0 ; k < 64 ; k ++ )
{
if ( base64char[k] == base64[i] )
temp[0]= k;
}
for ( k = 0 ; k < 64 ; k ++ )
{
if ( base64char[k] == base64[i+1] )
temp[1]= k;
}
for ( k = 0 ; k < 64 ; k ++ )
{
if ( base64char[k] == base64[i+2] )
temp[2]= k;
}
for ( k = 0 ; k < 64 ; k ++ )
{
if ( base64char[k] == base64[i+3] )
temp[3]= k;
}
bindata[j++] = ((unsigned char)(((unsigned char)(temp[0] << 2))&0xFC)) |
((unsigned char)((unsigned char)(temp[1]>>4)&0x03));
if ( base64[i+2] == '=' )
break;
bindata[j++] = ((unsigned char)(((unsigned char)(temp[1] << 4))&0xF0)) |
((unsigned char)((unsigned char)(temp[2]>>2)&0x0F));
if ( base64[i+3] == '=' )
break;
bindata[j++] = ((unsigned char)(((unsigned char)(temp[2] << 6))&0xF0)) |
((unsigned char)(temp[3]&0x3F));
}
return j;
}
/*从一个私钥pem文件中解析出module、exp数据至rsa_sk_t结构体*/
int ParseRsa2048PrivatePemFile(char* pemFilePath,rsa_sk_t *sk)
{
int length=0;
char* srcData = LoadPemFile(pemFilePath,&length);
if(srcData==NULL)
{
return -2; //打开文件错误
}
uint8_t destData[1193];
memset(destData,0,sizeof(destData));
length = base64_decode(srcData,destData);
free(srcData);
if(length>=1191)
{
int startIndex = 0;
if(destData[10]==1)
{
startIndex = 12;
}
else
{
startIndex = 11;
}
sk->bits = 2048;
memcpy(&sk->modulus [RSA_MAX_MODULUS_LEN-256 ], destData + startIndex, 256);
startIndex = startIndex + 256 + 2;
memcpy(&sk->public_exponet [RSA_MAX_MODULUS_LEN-3], destData + startIndex, 3);
if(destData[startIndex + 6]==1)
{
startIndex = startIndex + 8;
}
else
{
startIndex = startIndex + 7;
}
memcpy(&sk->exponent [RSA_MAX_MODULUS_LEN-256 ], destData + startIndex, 256);
if(destData[startIndex + 259]==1)
{
startIndex = startIndex + 261;
}
else
{
startIndex = startIndex + 260;
}
memcpy(&sk->prime1 [RSA_MAX_PRIME_LEN - 128 ], destData + startIndex, 128);
if(destData[startIndex + 131]==1)
{
startIndex = startIndex + 133;
}
else
{
startIndex = startIndex + 132;
}
memcpy(&sk->prime2 [RSA_MAX_PRIME_LEN - 128 ], destData + startIndex, 128);
if(destData[startIndex + 131]==1)
{
startIndex = startIndex + 133;
}
else if(destData[startIndex + 131]==0)
{
startIndex = startIndex + 132;
}
else
{
startIndex = startIndex + 131;
}
memcpy(&sk->prime_exponent1 [RSA_MAX_PRIME_LEN - 128 ], destData + startIndex, 128);
if(destData[startIndex + 131]==1)
{
startIndex = startIndex + 133;
}
else if(destData[startIndex + 131]==0)
{
startIndex = startIndex + 132;
}
else
{
startIndex = startIndex + 131;
}
memcpy(&sk->prime_exponent2 [RSA_MAX_PRIME_LEN - 128 ], destData + startIndex, 128);
if(destData[startIndex + 131]==1)
{
startIndex = startIndex + 133;
}
else if(destData[startIndex + 131]==0)
{
startIndex = startIndex + 132;
}
else
{
startIndex = startIndex + 131;
}
memcpy(&sk->coefficient [RSA_MAX_PRIME_LEN - 128 ], destData + startIndex, 128);
return 0;
}
else
{
return -1; //文件长度错误
}
return 0;
}
C语言解析pem公钥文件在上一篇文章里