1:rsa加密

原理:欧拉公式,本质,大数分解在现有计算力下,很难再极短时间内找到解


秘钥长度,指的是模值的位长度,主流为1024,2048...

RSA秘钥:(公钥+模值),(私钥+模值),成对出现

公钥指数:普遍为65537(0x10001,5bits)有意的把公钥指数选的小一点,但是对应私钥指数肯定很大,意图也很明确,大家都要用公钥加密,所以大家时间很宝贵,需要快一点,私钥是个人解密,所以慢一点。

私钥指数:习惯为小于1024bit的大整数

 

2:明文长度

网上有说明文长度小于等于密钥长度(Bytes)-11,这说法本身不太准确,会给人感觉RSA 1024只能加密117字节长度明文。实际上,RSA算法本身要求加密内容也就是明文长度m必须0<m<n,也就是说内容这个大整数不能超过n,否则就出错。那么如果m=0是什么结果?普遍RSA加密器会直接返回全0结果。如果m>n,运算就会出错?!那怎么办?且听下文分解。

只要用到padding,那么就要占用实际的明文长度,于是才有117字节的说法。我们一般使用的padding标准有NoPPadding、OAEPPadding、PKCS1Padding等,其中PKCS#1建议的padding就占用了11个字节。

 

3:密文长度

密文长度就是给定符合条件的明文加密出来的结果位长,这个可以确定,加密后的密文位长跟密钥的位长度是相同的

 

4:简介

OpenSSL是一个强大的安全套接字层密码库,囊括主要的密码算法、常用的密钥和证书封装管理功能及SSL协议,并提供丰富的应用程序供测试或其它目的使用。在OpenSSL被曝出现严重安全漏洞后,发现多数通过SSL协议加密的网站使用名为OpenSSL的开源软件包。由于这是互联网应用最广泛的安全传输方法,被网银、在线支付、电商网站、门户网站、电子邮件等重要网站广泛使用,所以该漏洞影响范围广大。

 

5:rsa使用


1)生成一个密钥:

openssl genrsa -out prikey.pem 1024

这里-out指定生成文件的。需要注意的是这个文件包含了公钥和密钥两部分,也就是说这个文件即可用来加密也可以用来解密。后面的1024是生成密钥的长度。

2)openssl可以将这个文件中的公钥提取出来:

openssl rsa -in prikey.pem -pubout -out pubkey.pem

-in指定输入文件,-out指定提取生成公钥的文件名。至此,我们手上就有了一个公钥,一个私钥(包含公钥)。现在可以将用公钥来加密文件了。

3)在目录中创建一个hello的文本文件,然后利用此前生成的公钥加密文件:

openssl rsautl -encrypt -in hello -inkey pubkey.pem -pubin -out hello.en

-in指定要加密的文件,-inkey指定密钥,-pubin表明是用纯公钥文件加密,-out为加密后的文件。

4)解密文件:

openssl rsautl -decrypt -in hello.en -inkey test.key -out hello.de

-in指定被加密的文件,-inkey指定私钥文件,-out为解密后的文件。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/err.h>

#define pubkey_path  "pubkey.pem"
#define prikey_path "prikey.pem"

char *auth_encrypt(char *data, char *key_path);    //加密
char *auth_decrypt(char *data, char *key_path);    //解密

// encrypt
char *auth_encrypt(char *data, char *key_path) {
	char *encrypted_data = NULL;
	RSA *rsa_key = NULL;
	FILE *file = NULL;
	int length = 0;	


	//1.打开秘钥文件
	if ((file = fopen(key_path, "rb")) == NULL) {
    	perror("fopen() error");
    	goto End;
	}

	//2.从公钥中获取 加密的秘钥
	if ((rsa_key = PEM_read_RSA_PUBKEY(file, NULL,NULL,NULL )) == NULL){
		ERR_print_errors_fp(stdout);
    	goto End;
	}

	length = strlen(data);
	
	encrypted_data = (char *)malloc(256);
	if (!encrypted_data) {
		perror("malloc() error");
		goto End;
	}
	
	memset(encrypted_data, 0, 256);
	
	//3. encrypt
	if (RSA_public_encrypt(length, (unsigned char*)data, (unsigned char*)encrypted_data, rsa_key, RSA_PKCS1_PADDING) < 0) {
		perror("RSA_public_encrypt()");
		goto End;
	}

End:
	if (rsa_key) {
		RSA_free(rsa_key);
	}
	if (file) {
		fclose(file);
	}
	
	return encrypted_data;
}

// decrypt
char *auth_decrypt(char *data, char *key_path) {
	char *decrypted_data = NULL;
	RSA *rsa_key = NULL;
	FILE *file = NULL;

	// 1.打开秘钥文件
    if ((file = fopen(key_path, "rb")) == NULL) {
        perror("fopen() error");
        goto End;
    }   

    // 2.从私钥中获取 解密的秘钥
    if ((rsa_key = PEM_read_RSAPrivateKey(file, NULL,NULL,NULL )) == NULL){
        ERR_print_errors_fp(stdout);
        goto End;
    }

    decrypted_data = (char *)malloc(245);
    if (!decrypted_data) {
        perror("malloc() error");
        goto End;
    }   
        
    memset(decrypted_data, 0, 245);

	// 3.decrypt
	if(RSA_private_decrypt(256, (unsigned char*)data, (unsigned char*)decrypted_data, rsa_key, RSA_PKCS1_PADDING) < 0) {
		perror("RSA_public_encrypt() error");
		goto End;
	}

End:
    if (rsa_key) {
        RSA_free(rsa_key);
    }   
    if (file) {
        fclose(file);
    }   
        
    return decrypted_data;
}


int main(void)
{
	char *source = "{\"cip\": \"20.31数数据\"}";
	char *ptf_en, *ptf_de;
	printf("source is :%s\n", source);

     //1.加密
    ptf_en = auth_encrypt(source, pubkey_path);
    if (ptf_en  == NULL){
        return 0;
    }
	else {
    	printf("ptf_en is   :%s\n", ptf_en);
    }
     //2.解密
	ptf_de = auth_decrypt(ptf_en, prikey_path);
	if (ptf_de == NULL){
        return 0;
	}
	else {
    	printf("ptf_de is   :%s\n", ptf_de);
	}
    if(ptf_en) free(ptf_en);
    if(ptf_de) free(ptf_de);

    return 0;
}

6:openssl 实现rsa,读取文件

参考:https://www.jianshu.com/p/51f8430f9c42