赞
踩
使用OpenSSL实现安全加密通信的服务器与客户端项目
https://gitee.com/lzhiqiang1999/sec-tans
欢迎star
1 特点:
二进制
字符串2 常用哈希算法:
以上说的散列值长度是二进制数据长度, 一般散列值使用 16 进制格式的数字串表示的, 看到的字符串长度是原来的2倍长。
3 OpenSSL下的函数使用
// 使用的头文件 #include <openssl/md5.h> #include <openssl/sha.h> # define MD5_DIGEST_LENGTH 16 // md5哈希值长度 // 初始化函数, 初始化参数 c int MD5_Init(MD5_CTX *c); 参数c: 传出参数 // 添加md5运算的数据,此时还没有计算哈希值 // 该函数可以进行多次数据添加 -> 函数多次调用 int MD5_Update(MD5_CTX *c, const void *data, size_t len); 参数: - c: MD5_Init() 初始化得到的 - data: 传入参数, 字符串 - len: data数据的长度 // 对添加的数据进行md5计算 int MD5_Final(unsigned char *md, MD5_CTX *c); 参数: - md: 传出参数, 存储得到的哈希值 - c: MD5_Init() 初始化得到的 // 通过传递的参数, 直接生成一个md5哈希值 // 只能添加一次数据 unsigned char *MD5(const unsigned char *d, size_t n, unsigned char *md); 参数: - d: 传入, 要进行md5运算的字符串 - n: 字符串的的长度 - md: 传出, 存储md5的哈希值 返回值: 这个地址的函数第三个参数md地址
1 特点:
2 3DES对称加密算法
重复3次DES,使用3个密钥,实现加密→解密→加密的过程。
3 AES对称加密算法
(1)特点:
(2)生成加密/解密的Key
#include <openssl/aes.h>
# define AES_BLOCK_SIZE 16 // 明文分组的大小
// 加密的时候调用
// aes中的秘钥格式 AES_KEY
// 封装加密时候使用的秘钥
AES_KEY key;
int AES_set_encrypt_key(const unsigned char *userKey, const int bits, AES_KEY *key);
// 封装解密时候使用的秘钥
int AES_set_decrypt_key(const unsigned char *userKey, const int bits, AES_KEY *key);
(3)CBC方式加密 - 密码分组链接模式
void AES_cbc_encrypt(const unsigned char *in, unsigned char *out, size_t length, const AES_KEY *key, unsigned char *ivec, const int enc); 参数: - in: 要加密/解密的数据 - out: 传出参数 - 加密: 存储密文 - 解密: 存储明文 - length: 必须是16的整数倍,out的长度 - (len = (字符串长度 + \0) % 16) == 0 - 如果不是在函数内部会自动填充 - 实际长度: ((len / 16) + 1 ) * 16 - key: 初始化之后的秘钥 - ivec: 初始化向量, 字符串 ==> 长度和分组长度相同 - enc: 指定数据要解密还是解密 - # define AES_ENCRYPT 1 -> 加密 - # define AES_DECRYPT 0 -> 解密
1 特点:
公钥
, 私钥
2 应用场景:
公钥加密, 私钥解密
私钥加密, 公钥解密
3 生成、保存、读取密钥
#include <openssl/rsa.h> // 申请一块内存, 存储了公钥和私钥 // 如果想得到RSA类型变量必须使用 RSA_new(); RSA *RSA_new(void); void RSA_free(RSA *); BIGNUM* BN_new(void); void BN_free(BIGNUM*); // 生成密钥对, 密钥对存储在内存中 int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb); 参数: - rsa: 通过RSA_new()获得 - bits: 秘钥长度, 单位: bit, 常用的长度 1024*n (n正整数) - e: 比较大的数(5位以内) - 通过 BN_new 得到对应的变量 - 初始化: BN_set_word(e, 12345); - cb: 回调函数, 用不到, 直接写NULL // rsa公钥私钥类型是一样的: RSA类型 // 将参数rsa中的公钥提取出来 RSA *RSAPublicKey_dup(RSA *rsa); - rsa参数: 秘钥信息 - 返回值: rsa公钥 // 将参数rsa中的私钥提取出来 RSA *RSAPrivateKey_dup(RSA *rsa); - rsa参数: 秘钥信息 - 返回值: rsa私钥 // 创建bio对象 // 密钥对写磁盘文件的时候, 需要编码 -> base64 // 封装了fopen BIO *BIO_new_file(const char *filename, const char *mode); 参数: - filename: 文件名 - mode: 文件打开方式和fopen打开方式的指定相同 int PEM_write_bio_RSAPublicKey(BIO* bp, const RSA* r); int PEM_write_bio_RSAPrivateKey(BIO* bp, const RSA* r, const EVP_CIPHER* enc, unsigned char* kstr, int klen, pem_password_cb *cb, void* u); RSA* PEM_read_bio_RSAPublicKey(BIO* bp, RSA** r, pem_password_cb *cb, void* u); RSA* PEM_read_bio_RSAPrivateKey(BIO* bp, RSA** r, pem_password_cb *cb, void* u); 参数: - bp: 通过BIO_new_file();函数得到该对象 - r: 传递一个RSA* rsa指针的地址, 传出参数-> 公钥/私钥 - cb: 回调函数, 用不到, 指定为NULL - u: 给回调传参, 用不到, 指定为NULL //从FILE中读公私钥 RSA* PEM_read_RSAPublicKey(FILE* fp, RSA** r, pem_password_cb *cb, void* u); RSA* PEM_read_RSAPrivateKey(FILE* fp, RSA** r, pem_password_cb *cb, void* u); // 写入文件中的公钥私钥数据不是原始数据, 写入的编码之后的数据 // 是一种pem的文件格式, 数据使用base64进行编码 int PEM_write_RSAPublicKey(FILE* fp, const RSA* r); int PEM_write_RSAPrivateKey(FILE* fp, const RSA* r, const EVP_CIPHER* enc, unsigned char* kstr, int klen, pem_password_cb *cb, void* u); 参数: - fp: 需要打开一个磁盘文件, 并且指定写权限 - r: 存储了密钥对 - 私钥独有的参数 - enc: 指定的加密算法 -> 对称加密 -> NULL - kstr: 对称加密的秘钥 -> NULL - klen: 秘钥长度 -> 0 - cb: 回调函数, 用不到, NULL - u: 给回调传参, 用不到, NULL
4 加密
以块的方式进行加密的, 加密的数据长度, 不能大于秘钥长度
- 假设: 秘钥长度: 1024bit = 128byte
数据被加密之后, 长度<秘钥长度
// 公钥加密 int RSA_public_encrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding); // 私钥解密 int RSA_private_decrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding); 签名使用 /// // 私钥加密 int RSA_private_encrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding); // 公钥解密 int RSA_public_decrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding); 参数: - flen: 要加密/解密的数据长度 长度 0 < flen <= 秘钥长度-11 - from: 传入, 要加密/解密的数据 - to: 传出, 存储数据, 加密->存储密文, 解密->存储明文 - rsa: 秘钥: 公钥/私钥 - padding: 指定填充方案, 数据填充, 不需要使用者做 - RSA_PKCS1_PADDING -> 使用该方案会填充11字节
5 签名
int RSA_sign(int type, const unsigned char *m, unsigned int m_length, unsigned char *sigret, unsigned int *siglen, RSA *rsa); 参数: - type: 使用的哈希算法 - NID_MD5 - NID_SHA1 - NID_SHA224 - ..... - m: 要进行签名的数据 - m_length: 要签名的数据长度 - 0 < m_length <= 秘钥长度-11 - sigret: 传出, 存储了签名之后的数据 -> 密文 - siglen: sigret密文长度 - rsa: 私钥 返回值: 判断函数状态 int RSA_verify(int type, const unsigned char *m, unsigned int m_length, const unsigned char *sigbuf, unsigned int siglen, RSA *rsa); 参数: - type: 使用的哈希算法, 和签名使用的哈希算法一致 - NID_MD5 - NID_SHA1 - NID_SHA224 - ..... - m: 进行签名的原始数据 -> 接收到的 - m_length: m参数字符串的长度 - sigbuf: 接收到的签名数据 - siglen: sigbuf接收到的签名数据的长度 - rsa: 公钥 返回值: 如果!=1: 失败 如果==1: 成功
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。