Openssl中的Libcrypto API

21 篇文章 1 订阅

简单例子

#include <openssl/conf.h>
#include <openssl/evp.h>
#include <openssl/err.h>
int main(int arc, char *argv[])
{ 
  /* Load the human readable error strings for libcrypto */
  ERR_load_crypto_strings();
/* Load all digest and cipher algorithms */
  OpenSSL_add_all_algorithms();//#1
/* Load config file, and other important initialisation */
  OPENSSL_config(NULL);
/* ... Do some crypto stuff here ... */
/* Clean up */
/* Removes all digests and ciphers */
  EVP_cleanup();
/* if you omit the next, a small leak may be left when you make use of the BIO (low level API) for e.g. base64 transformations */
  CRYPTO_cleanup_all_ex_data();
/* Remove error strings */
  ERR_free_strings();
return 0;
}

上层接口

又称EVP接口,即封装的接口
 提供了一套包括对称和非对称的加密解密函数,签名验签,生成哈希和MAC编码的方法。
底层接口
 直接接触独立的算法,但是在FIPS模式下运行时,底层接口不可用。
应答码
 成功返回1,失败返回0

if(1 != EVP_xxx()) goto err;
  if(1 != EVP_yyy()) goto err;
/* ... do some stuff ... */
err:
  ERR_print_errors_fp(stderr);

 但是并不是所有的都这样,避免粗心的方法是这么写 

 if (1 != some_openssl_function())
    /* handle error */

线程安全性
 目前openssl默认是线程不安全的。
 调用者需要提供各种回调方法来加锁,原子整数加法和线程Id检测。
 可以使用CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK)和CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK) 来设置有threadid,,dynlock和add_lock的回调。
 未来,openssl调本地线程将是自初始化线程安全的。
Fork安全性
 目前openssl的库函数方法并不都是异步信号安全的。
 因此,不要在signal handlers中调用openssl函数;
    不要在fork方法(exec或者_exit)的子进程中调用openssl函数;
    不要在pthread_atfork() handlers中调用openssl函数(fork自身是而且必须是异步信号安全的)。

初始化方法

#   define OpenSSL_add_all_algorithms() \
    OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS \
                        | OPENSSL_INIT_ADD_ALL_DIGESTS \
                        | OPENSSL_INIT_LOAD_CONFIG, NULL)
/*
 * If this function is called with a non NULL settings value then it must be
 * called prior to any threads making calls to any OpenSSL functions,
 * i.e. passing a non-null settings value is assumed to be single-threaded.
 */
int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings)来自init.c
{
    static int stoperrset = 0;
    if (stopped) {
        if (!stoperrset) {
            /*
             * We only ever set this once to avoid getting into an infinite
             * loop where the error system keeps trying to init and fails so
             * sets an error etc
             */
            stoperrset = 1;
            CRYPTOerr(CRYPTO_F_OPENSSL_INIT_CRYPTO, ERR_R_INIT_FAIL);
        }
        return 0;
    }
    if (!base_inited && !RUN_ONCE(&base, ossl_init_base))
        return 0;
    if ((opts & OPENSSL_INIT_NO_LOAD_CRYPTO_STRINGS)
            && !RUN_ONCE(&load_crypto_strings,
                         ossl_init_no_load_crypto_strings))
        return 0;
    if ((opts & OPENSSL_INIT_LOAD_CRYPTO_STRINGS)
            && !RUN_ONCE(&load_crypto_strings, ossl_init_load_crypto_strings))
        return 0;
    if ((opts & OPENSSL_INIT_NO_ADD_ALL_CIPHERS)
            && !RUN_ONCE(&add_all_ciphers, ossl_init_no_add_algs))
        return 0;
    if ((opts & OPENSSL_INIT_ADD_ALL_CIPHERS)
            && !RUN_ONCE(&add_all_ciphers, ossl_init_add_all_ciphers))
        return 0;
    if ((opts & OPENSSL_INIT_NO_ADD_ALL_DIGESTS)
            && !RUN_ONCE(&add_all_digests, ossl_init_no_add_algs))
        return 0;
    if ((opts & OPENSSL_INIT_ADD_ALL_DIGESTS)
            && !RUN_ONCE(&add_all_digests, ossl_init_add_all_digests))
        return 0;
    if ((opts & OPENSSL_INIT_ATFORK)
            && !openssl_init_fork_handlers())
        return 0;
    if ((opts & OPENSSL_INIT_NO_LOAD_CONFIG)
            && !RUN_ONCE(&config, ossl_init_no_config))
        return 0;
    if (opts & OPENSSL_INIT_LOAD_CONFIG) {
        int ret;
        CRYPTO_THREAD_write_lock(init_lock);
        appname = (settings == NULL) ? NULL : settings->appname;
        ret = RUN_ONCE(&config, ossl_init_config);
        CRYPTO_THREAD_unlock(init_lock);
        if (!ret)
            return 0;
    }
    if ((opts & OPENSSL_INIT_ASYNC)
            && !RUN_ONCE(&async, ossl_init_async))
        return 0;
#ifndef OPENSSL_NO_ENGINE
    if ((opts & OPENSSL_INIT_ENGINE_OPENSSL)
            && !RUN_ONCE(&engine_openssl, ossl_init_engine_openssl))
        return 0;
# if !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_DEVCRYPTOENG)
    if ((opts & OPENSSL_INIT_ENGINE_CRYPTODEV)
            && !RUN_ONCE(&engine_devcrypto, ossl_init_engine_devcrypto))
        return 0;
# endif
# ifndef OPENSSL_NO_RDRAND
    if ((opts & OPENSSL_INIT_ENGINE_RDRAND)
            && !RUN_ONCE(&engine_rdrand, ossl_init_engine_rdrand))
        return 0;
# endif
    if ((opts & OPENSSL_INIT_ENGINE_DYNAMIC)
            && !RUN_ONCE(&engine_dynamic, ossl_init_engine_dynamic))
        return 0;
# ifndef OPENSSL_NO_STATIC_ENGINE
#  if !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_HW_PADLOCK)
    if ((opts & OPENSSL_INIT_ENGINE_PADLOCK)
            && !RUN_ONCE(&engine_padlock, ossl_init_engine_padlock))
        return 0;
#  endif
#  if defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_NO_CAPIENG)
    if ((opts & OPENSSL_INIT_ENGINE_CAPI)
            && !RUN_ONCE(&engine_capi, ossl_init_engine_capi))
        return 0;
#  endif
#  if !defined(OPENSSL_NO_AFALGENG)
    if ((opts & OPENSSL_INIT_ENGINE_AFALG)
            && !RUN_ONCE(&engine_afalg, ossl_init_engine_afalg))
        return 0;
#  endif
# endif
    if (opts & (OPENSSL_INIT_ENGINE_ALL_BUILTIN
                | OPENSSL_INIT_ENGINE_OPENSSL
                | OPENSSL_INIT_ENGINE_AFALG)) {
        ENGINE_register_all_complete();
    }
#endif
#ifndef OPENSSL_NO_COMP
    if ((opts & OPENSSL_INIT_ZLIB)
            && !RUN_ONCE(&zlib, ossl_init_zlib))
        return 0;
#endif
    return 1;
}

在openssl源码中提供了一些demo可以看一下如何使用的。

  cms_comp.c
  cms_ddec.c
  cms_dec.c
  cms_denc.c
  cms_enc.c
  cms_sign.c
  cms_sign2.c
  cms_uncomp.c
  cms_ver.c
  pkread.c
  pkwrite.c
  smdec.c
  smenc.c
  smsign.c
  smsign2.c
  smver.c

参考:https://wiki.openssl.org/index.php/Libcrypto_API


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值