zoukankan      html  css  js  c++  java
  • 04.openssl支持底层api接口

    OpenSSL库由许多不同的包组成。 一些较低级别的软件包可以独立使用,而较高级别的软件包可以使用几个较低级别的软件包。 要有效地使用OpenSSL库,重要的是要了解我们已经介绍的密码学的基本概念,并熟悉更重要的补充软件包产品.
     
    4.1 Multithread Support(多线程支持)
    大多数现代操作系统都支持多线程应用程序,并且应用程序利用这种支持变得越来越普遍。 OpenSSL当然可以在多线程环境中使用; 然而,它要求开发人员做一些工作,以使程序线程安全。 许多开发人员在OpenSSL中犯的常见错误是他们认为库是线程安全的,不需要在应用程序中做任何特殊的事情。 这当然是一个不正确的假设,并且在多线程环境中设置OpenSSL失败会导致不可预知的行为,并且看起来随机的崩溃是非常难以调试的。
     
    应用程序有两种不同的回调方式可以在多线程环境中安全地运行。 静态锁提供了固定数量的可供OpenSSL使用的互斥锁。 动态锁定允许OpenSSL根据需要创建互斥锁。 OpenSSL目前不使用动态锁,但保留在将来这样做的权利。 如果您希望您的应用程序将来继续以最小的工作量继续工作,我们建议您现在实施静态和动态锁定。
     
    4.1.1 Static Locking Callbacks (静态锁回调)
    函数名称
    void locking_function(int mode, int n, const char *file, int line);
    功能
    下一个回调函数用于获取调用线程的唯一标识符。
    参数
    意义
    mode
    确定锁定功能应采取的操作。
    n
    应该获得或释放的锁的数量。
    file
    请求锁定操作发生的源文件的名称。
    line
    请求锁定操作发生的源代码行号。
     
     
    4.1.2 Dynamic Locking Callbacks(动态锁回调)
    步骤:创建锁->添加或删除锁->释放锁
    结构成员:
    struct CRYPTO_dynlock_value
    {
    MUTEX_TYPE mutex;
    };
     
     
    函数名称
     
    struct CRYPTO_dynlock_value *dyn_create_function(const char *file,int line);
    功能
    我们需要定义的第一个回调函数用于创建一个新的互斥体,OpenSSL将能够使用这个互斥体来保护数据结构
    参数
    意义
    file
    请求创建互斥锁的源文件的名称。
    line
    请求创建互斥锁的源代码行号。
     
     
    函数名称
     
    void dyn_lock_function(int mode, struct CRYPTO_dynlock_value*mutex, const char *file, int line);
    功能
    下一个回调函数用于获取或释放互斥锁。
    参数
    意义
    mode
    确定锁定功能应采取的操作。
    mutex
    应该被获得或释放的互斥体。
    file
    请求创建互斥锁的源文件的名称。
    line
    请求创建互斥锁的源代码行号。
     
     
    函数名称
     
    void dyn_destroy_function(struct CRYPTO_dynlock_value *mutex,const char *file, int line);
    功能
    销毁OpenSSL不再需要的互斥体。
    参数
    意义
    mutex
    应该销毁的互斥体
    file
    请求创建互斥锁的源文件的名称。
    line
    请求创建互斥锁的源代码行号。
     
     
    4.2 Internal Error Handling
    4.2.1 Manipulating Error Queues
    当OpenSSL库发生错误时,会记录大量的信息。 有些信息可能会自动尝试从错误中恢复,但其中大部分信息用于调试错误并将错误报告给用户。
     
    ERR包提供了六个基本功能,这些功能对于从错误队列中获取信息非常有用。 每个函数总是从队列中检索最旧的信息,以便按照生成的顺序返回错误。 记录的最基本的信息是错误代码,它描述发生的错误。 错误代码是一个32位整数,仅对OpenSSL有意义。 也就是说,OpenSSL为它可能遇到的任何错误条件定义了自己的唯一错误代码。 它不依赖于任何其他库(包括标准C运行库)定义的错误代码。 对于六个基本函数中的每一个,这个错误代码是函数的返回值。 如果队列中没有错误,则任何一个的返回都将是0,这也告诉我们0从来不是有效的错误代码。
     
     
    函数名称
     
    unsigned long ERR_get_error(void);
    功能
    错误码
     
     
    函数名称
     
    unsigned long ERR_peek_error(void);
    功能
    第二个函数也只从错误队列中检索错误代码,但是它不会被删除
    来自队列的错误报告,所以下一次调用将检索到相同的错误:
    参数
    意义
    mutex
    应该销毁的互斥体
    file
    请求创建互斥锁的源文件的名称。
    line
    请求创建互斥锁的源代码行号。
     
     
     
    函数名称
     
    unsigned long ERR_get_error_line(const char **file, int *line);
    功能
    第三个函数建立在由ERR_get_error和ERR_peek_error返回的信息上。 除了返回错误代码之外,
    它还会返回生成错误的源文件和源代码行的名称。 像ERR_get_error一样,它也从队列中删除错误报告.
    参数
    意义
    file
    接收生成错误的源文件的名称。
    line
    接收生成错误的源代码行号。
     
     
     
     
    函数名称
     
    unsigned long ERR_peek_error_line(const char **file, int *line);
    功能
     
    参数
    意义
    file
    接收生成错误的源文件的名称。
    line
    接收生成错误的源代码行号。
     
     
    函数名称
     
    unsigned long ERR_get_error_line_data(const char **file, int *line,const char **data, int *flags);
    功能
    获取错误行号和错误数据,并从队列中删除
    参数
    意义
    file
    接收生成错误的源文件的名称。
    line
    接收生成错误的源代码行号。
     
    data
    接收指向错误报告中附带的额外数据的指针。
     
    flags
    接收一组定义额外数据属性的标志。
     
     
     
    函数名称
     
    unsigned long ERR_peek_error_line_data(const char **file, int *line,const char **data, int *flags);
    功能
    获取错误行号和错误数据
    参数
    意义
    file
    接收生成错误的源文件的名称。
    line
    接收生成错误的源代码行号。
     
    data
    接收指向错误报告中附带的额外数据的指针。
     
    flags
    接收一组定义额外数据属性的标志。
     
     
    函数名称
    void ERR_clear_error(void);
    功能
    还有最后一个队列操作函数,我们将在这里讨论:清除函数
    错误队列。
    参数
    意义
     
     
    最后还有一个队列操作函数,我们将在这里讨论:清除错误队列的函数。 它将删除当前队列中的所有错误。 一般情况下,除非我们试图重置当前线程的错误状态,而不关心队列中的其他错误,否则不需要调用这个函数。 一旦被调用,没有办法恢复以前的错误,所以明智地使用它.
     
    4.3 Abstract Input/Output
    OpenSSL库提供了多种功能,用于创建和销毁BIO,将它们链接在一起以及读取或写入数据。 需要注意的是,BIO包是一个低级包,因此您必须小心使用它。 许多功能将允许您执行操作,以后可能导致不可预知的行为甚至崩溃。
     
    函数
    功能
    The BIO *BIO_new(BIO_METHOD *type);
    初始化BIO
    int BIO_set(BIO *bio, BIO_METHOD *type);
     
    int BIO_free(BIO *bio);
    当一个BIO不再需要时,它应该被销毁。
    void BIO_vfree(BIO *bio);
    BIO_vfree函数与BIO_free相同,只是它不返回值
    void BIO_free_all(BIO *bio);
    BIO_free_all函数可用于释放整个BIO链。
    BIO *BIO_push(BIO *bio, BIO *append);
    BIO_push函数会将BIO附加到BIO,从而创建或延长BIO链。
    BIO *BIO_pop(BIO *bio);
    BIO_pop函数将从指定的BIO链中删除指定的BIO并返回
    链中的下一个BIO或者如果没有下一个BIO,则为NULL。
    int BIO_read(BIO *bio, void *buf, int len);
    BIO_read的行为与C运行时函数读取几乎完全相同。
    int BIO_gets(BIO *bio, char *buf, int len);
    为从源BIO读取数据提供的另一个函数是BIO_gets,通常与C运行库对应的fgets的行为几乎相同。
    int BIO_write(BIO *bio, const void *buf, int len);
    从BIO_write的行为写
    int BIO_puts(BIO *bio, const char *buf);
    BIO_puts将指定的缓冲区解释为C风格的字符串,并尝试将其全部写出。
     
    我们提到,对于四个读写函数中的每一个,0或-1的返回值可能会或可能不一定表示发生错误。 提供了一套函数,可以让我们确定是否真的发生了错误,以及是否应该重试该操作。
     
    4.4 Random Number Generation
    整个OpenSSL库中的许多函数都需要随机数的可用性。 例如,创建会话密钥和生成公钥/私钥对都需要随机数字。 为了满足这个要求,RAND包提供了一个密码强的伪随机数发生器(PRNG)。 这意味着它产生的“随机”数据并不是真正的随机数,但在计算上难以预测。
     
    对于所有其他的随机数要求,由PRNG产生的伪随机数是适合使用。
    在许多Unix系统上,/ dev / random和/dev/urandom随机数产生器
    参考代码:
    int RAND_load_file(const char *filename, long bytes);
    int RAND_write_file(const char *filename);
    /* Read 1024 bytes from /dev/random and seed the PRNG with it */
    RAND_load_file("/dev/random", 1024);
    /* Write a seed file */
    RAND_write_file("prngseed.dat");
    /* Read the seed file in its entirety and print the number of bytes
    obtained */
    nb = RAND_load_file("prngseed.dat", -1);
    printf("Seeded the PRNG with %d byte(s) of data from prngseed.dat. ",nb);
     
    函数
    功能
    RAND_screen
    可以被周期性地调用以收集熵。
     RAND_load_file
    这将使PRNG的文件内容达到指定的字节数,或者如果限制被指定为-1,则将它的全部种子。
    RAND_write_file
    显示了该函数及其对应的一些示例用法,
    int RAND_egd(const char *path);
    RAND_egd尝试连接到指定的Unix域套接字。
    int RAND_egd_bytes(const char *path, int bytes);
    RAND_egd_bytes将尝试连接到指定的Unix域套接字。
    int RAND_query_egd_bytes(const char *path, unsigned char *buf, int
    bytes);
     
     
    4.5 Arbitrary Precision Math
    4.5.1 The Basics
    BN_bn2bin
    它会返回写入到提供的缓冲区的字节数。
    BN_bin2bn
    结果放入第三个指定的BIGNUM中论点,覆盖它以前可能持有的任何价值。
    BN_bn2hex
    存储在Cstyle字符串中的十六进制表示。
    BN_bn2dec
    函数BN_bn2dec将BIGNUM转换为存储在C-stylestring中的十进制表示形式。...
    BN_hex2bn
    将存储在C风格字符串中的数字的十六进制表示转换为BIGNUM。
    BN_dec2bn
    将十进制的转换成BIGNUM数据
     
    4.5.2 Mathematical Operations
    Function 
    Comments
    BN_add(r, a, b) 
    (r = a + b) r may be the same as a or b.
    BN_sub(r, a, b) 
    (r = a - b)
    BN_mul(r, a, b, ctx) 
    (r = a x b) r may be the same as a or b.
    BN_sqr(r, a, ctx) 
    (r = pow(a, 2)) r may be the same as a. This function is faster than
    BN_mul(r, a, a).
    BN_div(d, r, a, b, ctx) 
    (d = a / b, r = a % b) Neither d nor r may be the same as either a or b.
    Either d or r may be NULL.
    BN_mod(r, a, b, ctx) 
    (r = a % b)
    BN_nnmod(r, a, b, ctx) 
    (r = abs(a % b))
    BN_mod_add(r, a, b, m,
    ctx) 
    (r = abs((a + b) % m))
    BN mod sub(r, a, b, m,ctx)  
    (r = abs((a - b) % m))
    BN_mod_mul(r, a, b, m,ctx) 
    (r = abs((a x b) % m)) r may be the same as a or b.
    BN_mod_sqr(r, a, m,ctx) 
    (r = abs(pow(a, 2) % m))
    BN_exp(r, a, p, ctx) 
    (r = pow(a, p))
    BN_mod_exp(r, a, p, m,ctx) 
    (r = pow(a, 2) % m)
    BN_gcd(r, a, b, ctx) 
    Finds the greatest common divisor of a and b. r may be the same as a orb.
     
     
    4.5.3 Generating Prime Numbers(产生质素)
    函数
    BIGNUM *BN_generate_prime(BIGNUM *ret,
    int bits,
    int safe,
    BIGNUM*add,
    BIGNUM *rem,
    void (*callback)(int,int, void *),
    void *cb_arg);
    功能
    顾名思义,函数产生素数,更重要的是产生伪随机素数。
    参数
    意义
    ret
    用于接收生成的素数。 如果指定为NULL,则会创建一个新的BIGNUM,并使用BN_new进行初始化并返回。
    bits
    应该用来表示生成的素数的位数
    safe
    可以是零或非零,表示生成的素数是否应该是安全的。
    add
    用于指定生成的素数应具有的其他属性。
    rem
    用于指定生成的素数应具有的其他属性。
    callback
    在生成素数期间调用的函数,用于报告操作的状态。
    cb_arg
    如果指定了一个值,则仅用于传递给回调函数。
     
     
    ID string 
    Description
    openssl 
    引擎使用正常的内置函数进行加密操作。
    openbsd_dev_crypto 
    在OpenBSD操作系统上,这个引擎将使用操作系统内置的内核级加密技术。
    cswift 
    用于CryptoSwift加速硬件。
    chil 
    用于nCipher CHIL加速硬件。
    atalla 
    用于Compaq Atalla加速硬件。
    nuron 
    用于Nuron加速硬件。
    ubsec 
    用于Broadcom uBSec加速硬件。
    aep 
    用于Aep加速硬件。
    sureware 
    用于SureWare加速硬件。
     
     
    Table 4-3. Flags for ENGINE_set_default
     
    Flag
    Description
    ENGINE_METHOD_RSA
    将引擎使用限制为仅限RSA操作。
    ENGINE_METHOD_DSA
    将引擎使用限制为仅DSA操作。
    ENGINE_METHOD_DH
    将引擎使用限制为仅限DH操作。
    ENGINE_METHOD_RAND
    将引擎使用限制为只有随机数字操作。
    ENGINE_METHOD_CIPHERS
    将引擎使用限制为仅对称密码操作。
    ENGINE_METHOD_DIGESTS
    将引擎使用限制为仅消化操作。
    ENGINE_METHOD_ALL
    允许OpenSSL使用任何上述实现。
     
     
  • 相关阅读:
    模型定义
    聚合、原生和子查询
    PHP curl扩展
    时间查询
    查询表达式
    HTTP协议的Keep-Alive 模式
    抽象类可以没有抽象方法
    Nginx解决前端跨域问题,Nginx反向代理跨域原理
    Nginx配置文件不生效,Nginx配置文件重启也不生效
    php openssl加密解密函数
  • 原文地址:https://www.cnblogs.com/aixiaoxiaoyu/p/8125814.html
Copyright © 2011-2022 走看看