OpenSSL常用函数分类索引

OpenSSL常用函数分类索引

内存管理

void *OPENSSL_malloc(size_t num)
void *OPENSSL_zalloc(size_t num)
void *OPENSSL_realloc(void *addr, size_t num)
void *OPENSSL_memdup(void *data, size_t s)
void OPENSSL_free(void *addr)

char *OPENSSL_strdup(const char *str)
char *OPENSSL_strndup(const char *str, size_t s)
size_t OPENSSL_strlcat(char *dst, const char *src, size_t size);
size_t OPENSSL_strlcpy(char *dst, const char *src, size_t size);

void *OPENSSL_clear_realloc(void *p, size_t old_len, size_t num)
void OPENSSL_clear_free(void *str, size_t num)
void OPENSSL_cleanse(void *ptr, size_t len);

抽象IO库BIO

二进制数据与字符串互转

与16进制字符串互转

unsigned char *OPENSSL_hexstr2buf(const char *str, long *len);
char *OPENSSL_buf2hexstr(const unsigned char *buffer, long len);
int OPENSSL_hexchar2int(unsigned char c);

与base64字符串互转

#include <openssl/evp.h>

EVP_ENCODE_CTX *EVP_ENCODE_CTX_new(void);
void EVP_ENCODE_CTX_free(EVP_ENCODE_CTX *ctx);
int EVP_ENCODE_CTX_copy(EVP_ENCODE_CTX *dctx, EVP_ENCODE_CTX *sctx);
int EVP_ENCODE_CTX_num(EVP_ENCODE_CTX *ctx);
void EVP_EncodeInit(EVP_ENCODE_CTX *ctx);
int EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl,
                     const unsigned char *in, int inl);
void EVP_EncodeFinal(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl);
int EVP_EncodeBlock(unsigned char *t, const unsigned char *f, int n);

void EVP_DecodeInit(EVP_ENCODE_CTX *ctx);
int EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl,
                     const unsigned char *in, int inl);
int EVP_DecodeFinal(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl);
int EVP_DecodeBlock(unsigned char *t, const unsigned char *f, int n);

哈希算法

MD5/MD4/MD2

  1. 一步式操作

    unsigned char *MD5(const unsigned char *d, unsigned long n, unsigned char *md);
    
  2. 三段式操作

    int MD5_Init(MD5_CTX *c);
    int MD5_Update(MD5_CTX *c, const void *data, unsigned long len);
    int MD5_Final(unsigned char *md, MD5_CTX *c);
    

SHA1/SHA224/SHA256/SHA384/SHA512

  1. 一步式操作

    unsigned char *SHA1(const unsigned char *d, size_t n, unsigned char *md);
    
  2. 三段式操作

    int SHA1_Init(SHA_CTX *c);
    int SHA1_Update(SHA_CTX *c, const void *data, size_t len);
    int SHA1_Final(unsigned char *md, SHA_CTX *c);
    

对称加密

DES加解密

DES加解密模式参考man des_modes命令

常用的模式有:
1. ecb
2. cbc

DES加解密相关API参考man DES_random_key命令

加密过程有:
1. 单次加密:DES_ecb_encrypt 和 DES_xxx_encrypt
2. 双密码三次加密:DES_ecb2_encrypt 和 DES_ede2_xxx_encrypt
3. 三密码三次加密:DES_ecb3_encrypt 和 DES_ede3_xxx_encrypt
其中xxx是加密模式,对于cbc单次加密,应使用DES_ncbc_encrypt

密码每个字节的LSB是校验位,一组密码8个字节除了校验位,有效位只有56位,双密码是112位,三密码就是168位;

使用DES加密需要选择加密模式、加密过程、设置密钥,对使用初始向量的加密模式还需要设置初始向量,加密模式加密过程通常为双方约定,密钥和初始向量则通过握手过程协商获得或通过其他渠道获得。

使用步骤:

生成或者获取密钥:
void DES_random_key(DES_cblock *ret);

需要从密码字符串生成密钥,推荐使用hash算法,而不是用DES_string_to_key或DES_string_to_2key

根据需要对密钥设置奇校验
void DES_set_odd_parity(DES_cblock *key);
根据需要检查密钥强度
int DES_is_weak_key(const_DES_cblock *key);
由密钥生成key_schedule
int DES_set_key_checked(const_DES_cblock *key, DES_key_schedule *schedule);
void DES_set_key_unchecked(const_DES_cblock *key, DES_key_schedule *schedule);
对于需要初始向量的加密模式,还需要选择或生成初始向量
执行加解密
void DES_ecb_encrypt(const_DES_cblock *input, DES_cblock *output,
                     DES_key_schedule *ks, int enc);
void DES_ecb2_encrypt(const_DES_cblock *input, DES_cblock *output,
                      DES_key_schedule *ks1, DES_key_schedule *ks2, int enc);
void DES_ecb3_encrypt(const_DES_cblock *input, DES_cblock *output,
                      DES_key_schedule *ks1, DES_key_schedule *ks2,
                      DES_key_schedule *ks3, int enc);

void DES_ncbc_encrypt(const unsigned char *input, unsigned char *output,
                      long length, DES_key_schedule *schedule, DES_cblock *ivec,
                      int enc);
void DES_ede2_cbc_encrypt(const unsigned char *input, unsigned char *output,
                          long length, DES_key_schedule *ks1,
                          DES_key_schedule *ks2, DES_cblock *ivec, int enc);
void DES_ede3_cbc_encrypt(const unsigned char *input, unsigned char *output,
                          long length, DES_key_schedule *ks1,
                          DES_key_schedule *ks2, DES_key_schedule *ks3,
                          DES_cblock *ivec, int enc);

其他对称加密算法还有AES、Blowfish、CAST、IDEA、RC2、RC5,都支持电子密码本模式(ECB)、加密分组链接模式(CBC)、加密反馈模式(CFB)和输出反馈模式(OFB)四种常用的分组密码加密模式。其中,AES使用的加密反馈模式(CFB)和输出反馈模式(OFB)分组长度是128位,其它算法使用的则是64位。

以上都是分组加密算法,分组加密每次计算需要一种数据(64位或128位),对于最后一组数据位数不够时根据约定补padding,中间过程如果数据不够需要等待。下面介绍的是流式加密算法RC4

RC4加解密

生成密钥
void RC4_set_key(RC4_KEY *key, int len, const unsigned char *data);
数据加解密
void RC4(RC4_KEY *key, unsigned long len, const unsigned char *indata,
         unsigned char *outdata);

大数操作BN

BN与字符串互转

char *BN_bn2hex(const BIGNUM *a);
char *BN_bn2dec(const BIGNUM *a);
int BN_hex2bn(BIGNUM **a, const char *str);
int BN_dec2bn(BIGNUM **a, const char *str);

BN与二进制内存数据互转

int BN_bn2bin(const BIGNUM *a, unsigned char *to);
int BN_bn2binpad(const BIGNUM *a, unsigned char *to, int tolen);
BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret);

BN输出到文件

int BN_print(BIO *fp, const BIGNUM *a);
int BN_print_fp(FILE *fp, const BIGNUM *a);

PEM文件操作

PEM格式密钥保存和读取

int PEM_write_RSAPrivateKey(FILE *fp, RSA *x, const EVP_CIPHER *enc,
                            unsigned char *kstr, int klen,
                            pem_password_cb *cb, void *u);
int PEM_write_bio_RSAPrivateKey(BIO *bp, RSA *x, const EVP_CIPHER *enc,
                                unsigned char *kstr, int klen,
                                pem_password_cb *cb, void *u);
int PEM_write_RSAPublicKey(FILE *fp, RSA *x);
int PEM_write_bio_RSAPublicKey(BIO *bp, RSA *x);
int PEM_write_RSA_PUBKEY(FILE *fp, RSA *x); 
int PEM_write_bio_RSA_PUBKEY(BIO *bp, RSA *x);

RSA *PEM_read_RSAPrivateKey(FILE *fp, RSA **x,
                            pem_password_cb *cb, void *u);
RSA *PEM_read_bio_RSAPrivateKey(BIO *bp, RSA **x,
                                pem_password_cb *cb, void *u);
RSA *PEM_read_RSAPublicKey(FILE *fp, RSA **x,
                           pem_password_cb *cb, void *u);
RSA *PEM_read_bio_RSAPublicKey(BIO *bp, RSA **x,
                               pem_password_cb *cb, void *u);
RSA *PEM_read_RSA_PUBKEY(FILE *fp, RSA **x,
                         pem_password_cb *cb, void *u);
RSA *PEM_read_bio_RSA_PUBKEY(BIO *bp, RSA **x,
                             pem_password_cb *cb, void *u);

EVP接口

int PEM_write_bio_PrivateKey(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc,
                             unsigned char *kstr, int klen,
                             pem_password_cb *cb, void *u);
int PEM_write_bio_PrivateKey_traditional(BIO *bp, EVP_PKEY *x,
                                         const EVP_CIPHER *enc,
                                         unsigned char *kstr, int klen,
                                         pem_password_cb *cb, void *u);
int PEM_write_PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc,
                         unsigned char *kstr, int klen,
                         pem_password_cb *cb, void *u);
int PEM_write_bio_PUBKEY(BIO *bp, EVP_PKEY *x);
int PEM_write_PUBKEY(FILE *fp, EVP_PKEY *x);

EVP_PKEY *PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x,
                                  pem_password_cb *cb, void *u);
EVP_PKEY *PEM_read_PrivateKey(FILE *fp, EVP_PKEY **x,
                              pem_password_cb *cb, void *u);
EVP_PKEY *PEM_read_bio_PUBKEY(BIO *bp, EVP_PKEY **x,
                              pem_password_cb *cb, void *u);
EVP_PKEY *PEM_read_PUBKEY(FILE *fp, EVP_PKEY **x,
                          pem_password_cb *cb, void *u);

非对称加密

RSA加解密

生成密钥
int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb);
int RSA_generate_multi_prime_key(RSA *rsa, int bits, int primes, BIGNUM *e, BN_GENCB *cb);
密钥参数打印
int RSA_print(BIO *bp, RSA *x, int offset);
int RSA_print_fp(FILE *fp, RSA *x, int offset);```
密钥的提取和指定
void RSA_get0_key(const RSA *r,
                  const BIGNUM **n, const BIGNUM **e, const BIGNUM **d);
int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d);

有了公钥和私钥数据n,e,d,就可以结合BN(BIGNUM)相关函数做任意格式的保存;但经常使用的方法是配合使用PEM相关的API来保存和读取公钥与私钥数据

密钥的保存和读取

参考前面PEM格式密钥保存和读取

检测私钥是否正确
#include <openssl/rsa.h>

int RSA_check_key_ex(RSA *rsa, BN_GENCB *cb);

int RSA_check_key(RSA *rsa);
加解密
#include <openssl/rsa.h>

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);

以下私钥加密,公钥解密方法通常用于签名

#include <openssl/rsa.h>

int RSA_private_encrypt(int flen, unsigned char *from,
                        unsigned char *to, RSA *rsa, int padding);

int RSA_public_decrypt(int flen, unsigned char *from,
                       unsigned char *to, RSA *rsa, int padding);
签名和验签
#include <openssl/rsa.h>

int RSA_sign(int type, const unsigned char *m, unsigned int m_len,
             unsigned char *sigret, unsigned int *siglen, RSA *rsa);

int RSA_verify(int type, const unsigned char *m, unsigned int m_len,
               unsigned char *sigbuf, unsigned int siglen, RSA *rsa);
  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

飞花丝雨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值