openssl 框架中的另一个重头戏就是EVP接口,它提供了所有的加密和解密实现,不但封装了已有的著名算法,而且其简单易用的接口可以让你自己轻松实现一个算法,这 就增强了它的可扩展性,基本上,openssl只是提供了机制框架,策略由用户实现。EVP接口的重要数据结构如下:
typedef struct evp_cipher_st
{
int nid; //对象识别ID
int block_size; //加密数据的长度
int key_len; //加密算法缺省密钥长度
int iv_len;
unsigned long flags;
int (*init)(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc);
int (*do_cipher)(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl);//加密或者解密
int (*cleanup)(EVP_CIPHER_CTX *); //清理析构回调函数
int ctx_size;
int (*set_asn1_parameters)(EVP_CIPHER_CTX *, ASN1_TYPE *);
int (*get_asn1_parameters)(EVP_CIPHER_CTX *, ASN1_TYPE *);
int (*ctrl)(EVP_CIPHER_CTX *, int type, int arg, void *ptr); //操作函数
void *app_data;
}EVP_CIPHER;
typedef struct evp_cipher_ctx_st
{
const EVP_CIPHER *cipher; //加密结构
ENGINE *engine;
int encrypt; //指示加密还是解密
int buf_len; //该结构缓冲区里面当前的数据长度
unsigned char oiv[EVP_MAX_IV_LENGTH];
unsigned char iv[EVP_MAX_IV_LENGTH];
unsigned char buf[EVP_MAX_BLOCK_LENGTH];
int num;
void *app_data;
int key_len; //密钥长度
unsigned long flags;
void *cipher_data;
int final_used;
int block_mask;
unsigned char final[EVP_MAX_BLOCK_LENGTH];
} EVP_CIPHER_CTX;
我 们看一下EVP有几种被使用的方式,首先它可以直接被使用,也就是直接生成一个特定加密算法EVP_CIPHER对象即可,然后调用其do_cipher 实现加密或者解密,另外如果我们在更加复杂的环境或者更加复杂的流程中使用它的话,那么就需要更大的数据结构EVP_CIPHER_CTX来作为一个上下 文环境来包容一个特定的加密解密算法,比如它可以包含在一个BIO之中:
typedef struct enc_struct
{
int buf_len;
int buf_off;
int cont; /* <= 0 when finished */
int finished;
int ok; /* bad decrypt */
EVP_CIPHER_CTX cipher;
char buf[ENC_BLOCK_SIZE+BUF_OFFSET+2];
} BIO_ENC_CTX;
本 身来讲,BIO中就有那么一种过滤类型的BIO专门就是为了加密解密用的。另外用于ssl是必然的,本身openssl中最拿手的就是这个EVP了,所有 的安全加密解密都由它来实现,ssl本身就是安全相关的协议,因此实用角度,EVP的意义对于openssl来讲比BIO更加重要。因此正如下文讲的 SSL结构体中就有一个EVP的指针。
附:加密
迄今为止,加密算法分为对称算法和不对称算法又称公钥算法,公钥算法自然不必多说,依赖数 学函数的反解困难性,安全性大大提供,但是缺点就是太聪明了,导致不太容易被硬件实现,或者用软件实现速度也不佳,而对称算法由于基本都是靠置换和移位来 加密的,而计算机硬件最擅长的可能就是做这种事情了,因此往往都是使用公钥算法交换对称密钥,然后用对称算法进行加密,但是问题是,为何众人皆知的过程最 终就可以加密数据呢?要知道S盒之类的可是公开的啊。其实很简单,这就是混乱和和谐的辩证,1000中和谐只要加入1个混乱,那么结果就是混乱的,这是信 息熵决定的。和谐和混乱本来就是不是对称的,因为和谐的信息熵更低,而混乱的信息熵更高,同样数量的和谐和混乱信息熵不同,因此人们彻底搞清楚信息含义所 付出的努力也不会相同。如果一个数字序列,很和谐,1,2,3,4..突然在403后面来了一个37,是不是晕了,前面的假设被推翻,有时候就是这样,混 乱不一定越多越乱,在有序当中插入一点混乱就不得了了,对称加密算法中的置换其实就是为了掩人耳目的。事实证明,如果完全用混乱的加密算法,效率很差,效 果不一定多好,混入一些可以高效实现的置换,移位,不会因为这些操作是有序的就很容易被破解,效率还可以得到大大提升,要点就是整个加密过程不是完全的有 序的,而是混杂进了一点点无序,哪怕每次加一点或者说线性加入,解密难度将会指数级上升。