RSA2048源码,感谢作者!
需求:从服务器端获得RSA公钥字符串和待解密的字符串,用公钥解密字符串
解决:
1、将RSA公钥转换为十六进制
2、将待解密字符串转换为十六进制
3、用公钥解密字符串,输出结果
PKCS#1填充原理
RSA2048加密,处理数据的缓冲区大小为(2048 + 7)/8
待加/解密的数据长度已知
1、公钥加密:
如果(待加密数据长度+11)没超过256,开始填充
把待加密数据放在缓冲区最后,在缓冲区头部开始填充
填充数据为:0、2、(不为零的随机数)、0、(待加密数据)
填充完后进行加密。
2、私钥解密:
先用私钥进行解密,遍历解密后的数据,查找 0、2、~~~、0,然后取出解密后的数据。
私钥加密填充的是: 0、 1、(不为零的随机数)、0、(待加密的数据)
公钥解密大致与上述相同。
main.c
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>
#include "rsa.h"
#define KEY_M_BITS 2048
//str_to_hex
uint32_t StringToHex(char *input_str, unsigned char *output_hex)
{
int str_pub_key_len;
unsigned char out[300] = { 0 };
char *p = input_str;
char high = 0, low = 0;
int cnt = 0;
int tmplen;
tmplen = strlen(p);
while (cnt < (tmplen / 2))
{
high = ((*p > '9') && ((*p <= 'F') || (*p <= 'f'))) ? *p - 48 - 7 : *p - 48;
low = (*(++p) > '9' && ((*p <= 'F') || (*p <= 'f'))) ? *p - 48 - 7 : *(p)-48;
out[cnt] = ((high & 0x0f) << 4 | (low & 0x0f));
p++;
cnt++;
}
if (tmplen % 2 != 0) out[cnt] = ((*p > '9') && ((*p <= 'F') || (*p <= 'f'))) ? *p - 48 - 7 : *p - 48;
str_pub_key_len = tmplen / 2 + tmplen % 2;
memcpy(output_hex, out, str_pub_key_len);
return tmplen / 2 + tmplen % 2;
}
//解码
uint32_t rsa_dec(uint8_t *input, uint32_t inputLen, uint8_t *key_m, uint32_t key_len, uint8_t *output){
int ret;
rsa_pk_t pk = {0};
uint8_t key_e[] = { 0x01, 0x00, 0x01 }; //65537
uint32_t output_len = 0;
pk.bits = KEY_M_BITS;
memcpy(&pk.modulus [RSA_MAX_MODULUS_LEN - key_len], key_m, key_len);
memcpy(&pk.exponent [RSA_MAX_MODULUS_LEN-sizeof(key_e) ], key_e, sizeof(key_e ));
ret = rsa_public_decrypt(output, &output_len, input, inputLen, &pk);
return output_len;
}
int main(int argc, char *argv[])
{
uint32_t i;
uint8_t data[256] = { 0 };//待解密
uint32_t data_len;
uint8_t key_m[256] = { 0 };//RSA公钥
uint32_t key_len;
uint8_t output[256] = { 0 };//输出
uint32_t output_len;
char *str_pub_key = "eb2489a34cfbdcacfdb95ffd4654c7c6378d062a15997fa0ebc60cb4730f1cc5d56cb86e8cbaafef6f2b2bf2042ebb089bed5f709d77316e29002673a459a64fd3ff71feff73790ae89c0769e9a4fde02a19bebec92e295c54361d4676c16d562f981f13e8cc2c17e66759514caf339b511c22435742507c1e1a5286ad6f85dfabf8427c5ca27ab8659fef4b80e395ed6df033e2157efc8b87b5b2826bd7791a153355765db7118a9848a6a57917f843257f1ba96c547d1f19fbfeb5752eac907e015a7c2c46f643a59274a9f5bb6105222979249b51a7a391466e367ac6d6ec269a89b4cf2a2401a91171b97d90a3bf7905fed95fb966da9c6ea9404c42cacd";
char *str_encrypt = "0e7ac2c4841abd61310d0a74129d96531aab58ba3f8f7a0f9ba9a4ab663789312180faf8fb61b1081d3e5276ab86f8160a5197b6a9fceabef85ec46c018de6c859f871c86d08ffa44055358df9f2591bf3973b23fdcdd42f02b0f48c6cd842adfd76aead8854adc8459e19c6c3f05c0574c7397aff0d894b2f90e0e33393cc1db285c0212a100ca7fc8456404f5ae1005003a5dc7f5ec66f3b3dc3c67bdd6524c7b10b0e354f0ebeced6e93626468e8c7c8637969403ca979e036a941001927f5953aa10cd77dcd687d99771e9dd9368fae41c5bdb1abdaa46c681331ce3562085c97614477ec7a16a5611ab415cf7e8fc393ea2e3d7be9506710af1f888478d";
//str_to_hex
key_len = StringToHex(str_pub_key, key_m);
data_len = StringToHex(str_encrypt, data);
//decryption
output_len = rsa_dec(data, data_len, key_m, key_len, output);
for (i = 0; i < output_len; i++){
printf("%c", output[i]);
}
printf("\n");
return 0;
}
结果: