PEM_read_PUBKEY和PEM_read_RSA_PUBKEY两个函数都可以从PEM格式的文件中读取公钥,但它们处理公钥的方式不同。
- PEM_read_PUBKEY函数读取的是一个包含任何类型公钥的PEM文件,这个文件通常以"-----BEGIN PUBLIC KEY-----"开始。这个函数返回一个EVP_PKEY结构,这是一个可以包含任何类型公钥的通用结构。
- PEM_read_RSA_PUBKEY函数读取的是一个包含RSA公钥的PEM文件,这个文件通常以"-----BEGIN RSA PUBLIC KEY-----"开始。这个函数返回一个RSA结构,这是一个专门用于表示RSA公钥的结构。
因此,如果你有一个包含RSA公钥的PEM文件,你可以使用这两个函数中的任何一个来读取它,但是你得到的结果将是不同类型的结构。如果你使用PEM_read_PUBKEY函数,你将得到一个EVP_PKEY结构,你可以使用EVP_PKEY相关的函数来处理这个公钥。如果你使用PEM_read_RSA_PUBKEY函数,你将得到一个RSA结构,你可以使用RSA相关的函数来处理这个公钥。
此外,这两种类型的PEM格式的公钥在编码方式上也有所不同。"-----BEGIN PUBLIC KEY-----“格式的公钥使用的是X.509 SubjectPublicKeyInfo格式,而”-----BEGIN RSA PUBLIC KEY-----"格式的公钥使用的是PKCS#1 RSAPublicKey格式。这两种格式的主要区别在于,SubjectPublicKeyInfo格式包含了公钥的类型信息,而RSAPublicKey格式没有。
将X.509格式的公钥转换为PKCS#1 RSAPublicKey格式的PEM文件:
openssl rsa -pubin -inform PEM -RSAPublicKey_out -in public_key.pem -out public_key_rsa.pem
将PKCS#1 RSAPublicKey格式的PEM文件转换为X.509 SubjectPublicKeyInfo格式的PEM文件
openssl rsa -pubin -inform PEM -in public_key_rsa.pem -outform PEM -out public_key_x509.pem
EVP_PKEY和RSA都是OpenSSL库中的数据类型,它们都用于表示密钥,但它们的用途和功能有所不同。
- RSA:这是一个专门用于表示RSA密钥的数据类型。它包含了RSA密钥的所有组成部分(例如,公钥和私钥的模数和指数)。你可以使用OpenSSL库中的一些函数(例如,RSA_generate_key_ex)来生成RSA密钥,然后使用其他函数(例如,RSA_public_encrypt和RSA_private_decrypt)来进行加密和解密操作。
- EVP_PKEY:这是一个更通用的密钥表示类型,可以表示各种类型的密钥,包括但不限于RSA密钥。EVP_PKEY对象可以包含RSA密钥、DSA密钥、EC密钥等。使用EVP_PKEY的优点是,你可以编写与密钥类型无关的代码,然后在运行时选择使用哪种类型的密钥。例如,你可以使用相同的EVP_PKEY接口来处理RSA密钥和EC密钥,而不需要为每种密钥类型编写不同的代码。
总的来说,如果你只需要处理RSA密钥,那么使用RSA类型可能会更简单。但是,如果你需要处理多种类型的密钥,或者你想使用OpenSSL的高级加密功能(例如,自动填充模式和摘要算法),那么使用EVP_PKEY可能会更方便。
char* readPublicKeyFromPEM(const char* filePath) {
FILE* file = fopen(filePath, "r");
if (file == NULL) {
printf("file null \r\n");
return NULL;
}
EVP_PKEY* publicKey = PEM_read_PUBKEY(file, NULL, NULL, NULL);
fclose(file);
if (publicKey == NULL) {
// 处理读取公钥错误
ERR_print_errors_fp(stderr);
printf("read_PUBKEY error \r\n");
return NULL;
}
BIO* bio = BIO_new(BIO_s_mem());
PEM_write_bio_PUBKEY(bio, publicKey);
char* publicKeyStr = NULL;
long len = BIO_get_mem_data(bio, &publicKeyStr);
char* result = malloc(len + 1);
memcpy(result, publicKeyStr, len);
result[len] = '\0';
printf("%s \r\n",result);
BIO_free(bio);
EVP_PKEY_free(publicKey);
return result;
}
RSA *publicRsa = NULL;
void ReadPublicKey(void)
{
FILE *fp = NULL;
if ((fp = fopen("./public.pem", "r")) == NULL)
{
printf("pubkey_path error\n");
return -1;
}
if ((publicRsa = PEM_read_RSA_PUBKEY(fp, NULL, NULL, NULL)) == NULL)
{
printf("PEM_read_RSA_PUBKEY error\n");
return -1;
}
fclose(fp);
int rsa_len = RSA_size(publicRsa);
BIO* bio = BIO_new(BIO_s_mem());
if (PEM_write_bio_RSAPublicKey(bio, publicRsa) != 1)
{
// handle error
}
char* publicKeyStr = NULL;
long len = BIO_get_mem_data(bio, &publicKeyStr);
char* result = malloc(len + 1);
memcpy(result, publicKeyStr, len);
result[len] = '\0';
printf("%s \r\n",result);
BIO_free(bio);
RSA_free(publicRsa);
}