基于openssl编程实现加解密及摘要系统说明书.doc_第1页
基于openssl编程实现加解密及摘要系统说明书.doc_第2页
基于openssl编程实现加解密及摘要系统说明书.doc_第3页
基于openssl编程实现加解密及摘要系统说明书.doc_第4页
基于openssl编程实现加解密及摘要系统说明书.doc_第5页
已阅读5页,还剩24页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

目录基于openssl编程实现加解密及摘要系统3课程设计的性质和目的3课程设计选题3实现的基本原理3第1章 引言61.1设计目的61.2设计任务61.3设计要求61.4设计简介7第2章 程序设计92.1实验环境92.2理论依据92.3编程原理92.4 Openssl简介92.4.1 Openssl之对称算法92.4.2 Openssl之摘要算法122.4.3 Openssl之公钥算法RSA132.5程序设计说明142.5.1 文件操作模块142.5.2 对称算法实现模块142.5.3 摘要算法实现模块152.5.4 RSA算法实现模块162.5.5 数字信封实现模块17第3章 结论193.1程序运行结果203.11 程序运行的主界面203.12 对称加密解密模块213.13 非对称算法RSA模块243.14 摘要算法模块263.15 数字信封模块273.2结论293.3建议303.4尚未解决的问题30第4章 设计体会30参考文献31基于openssl编程实现加解密及摘要系统课程设计的性质和目的信息安全课程设计是课程教学中的一项重要内容,是完成教学计划达到教学目标的重要环节,是教学计划中综合性较强的实践教学环节,它对帮助学生全面牢固地掌握课堂教学内容、培养学生的实践和实际动手能力、提高学生全面素质具有很重要的意义。信息安全是一门理论性和实用性都很强的课程,也是信息安全课程设计环节应占有重要的地位,密码技术为现代电子商务、网络安全等必修之工具。本课次程设计应达到以下目的:1了解如何快速实现加密与解密并运用于实际应用中。 2提高应用C/C+ 等编程语言、数据结构编写大型算法的能力。3提高对于信息安全方面的软件包的应用能力。课程设计选题1. 利用Openssl实现常见对称算法(DES、AES、IDEA .)的实现,并能应用于实际。2. 利用Openssl实现常见公钥算法(RSA)的实现,并能应用于实际。3. 利用Openssl实现常见摘要算法(md2、md4、md5、rmd160、sha、sha1)的实现,并能应用于实际。3. 利用Openssl实现数字信封的封装于拆封。有一定得实际应用价值。实现的基本原理1. 对称算法:对称算法使用一个密钥。给定一个明文和一个密钥,加密产生密文,其长度和明文大致相同。解密时,使用读密钥与加密密钥相同。对称算法主要有四种加密模式:(1) 电子密码本模式 Electronic Code Book(ECB) 这种模式是最早采用和最简单的模式,它将加密的数据分成若干组,每组的大小跟加密密钥长度相同,然后每组都用相同的密钥进行加密。其缺点是:电子编码薄模式用一个密钥加密消息的所有块,如果原消息中重复明文块,则加密消息中的相应密文块也会重复,因此,电子编码薄模式适于加密小消息。(2) 加密块链模式 Cipher Block Chaining(CBC)CBC模式的加密首先也是将明文分成固定长度的块,然后将前面一个加密块输出的密文与下一个要加密的明文块进行异或操作,将计算结果再用密钥进行加密得到密文。第一明文块加密的时候,因为前面没有加密的密文,所以需要一个初始化向量。跟ECB方式不一样,通过连接关系,使得密文跟明文不再是一一对应的关系,破解起来更困难,而且克服了只要简单调换密文块可能达到目的的攻击。(3) 密反馈模式 Cipher Feedback Mode(CFB)面向字符的应用程序的加密要使用流加密法,可以使用加密反馈模式。在此模式下,数据用更小的单元加密,如可以是8位,这个长度小于定义的块长(通常是64位)。其加密步骤是:a) 使用64位的初始化向量。初始化向量放在移位寄存器中,在第一步加密,产生相应的64位初始化密文;b)始化向量最左边的8位与明文前8位进行异或运算,产生密文第一部分(假设为c),然后将c传输到接收方;c) 向量的位(即初始化向量所在的移位寄存器内容)左移8位,使移位寄存器最右边的8位为不可预测的数据,在其中填入c的内容;d) 第1-3步,直到加密所有的明文单元。解密过程相反(4) 输出反馈模式 Output Feedback Mode(OFB)输出反馈模式与CFB相似,惟一差别是,CFB中密文填入加密过程下一阶段,而在OFB中,初始化向量加密过程的输入填入加密过程下一阶段。2. 公钥算法在公钥密码系统中,加密和解密使用的是不同的密钥,这两个密钥之间存在着相互依存关系:即用其中任一个密钥加密的信息只能用另一个密钥进行解密。这使得通信双方无需事先交换密钥就可进行保密通信。其中加密密钥和算法是对外公开的,人人都可以通过这个密钥加密文件然后发给收信者,这个加密密钥又称为公钥;而收信者收到加密文件后,它可以使用他的解密密钥解密,这个密钥是由他自己私人掌管的,并不需要分发,因此又成称为私钥,这就解决了密钥分发的问题。主要的公钥算法有:RSA、DSA、DH和ECC。(本次课程设计只做了RSA,这里也只介绍RSA)RSA算法:RSA算法是第一个既能用于数据加密也能用于数字签名的算法,因此它为公用网络上信息的加密和鉴别提供了一种基本的方法。它通常是先生成一对RSA 密钥,其中之一是保密密钥,由用户保存;另一个为公开密钥,可对外公开,甚至可在网络服务器中注册,人们用公钥加密文件发送给个人,个人就可以用私钥解密接受。为提高保密强度,RSA密钥至少为500位长,一般推荐使用1024位。RSA公钥密码算法是目前网络上进行保密通信和数字签名的最有效的安全算法之一。RSA算法的安全性基于数论中大素数分解的困难性,所以,RSA需采用足够大的整数。因子分解越困难,密码就越难以破译,加密强度就越高。其算法如下:A. 选择两质数p、qB. 计算n = p * qC. 计算n的欧拉函数(n) = (p - 1)(q - 1)D. 选择整数e,使e与(n)互质,且1 e Options-Directories 在showdirectories里选择Include files将头文件文件夹的路径添加进,然后选择Library files将Lib文件夹路径添加进去确定即可。2.4.1 Openssl之对称算法对称加密算法封装的函数系列名字是以EVP_Encrypt*.*开头的,其实,这些函数只是简单调用了EVP_Cipher*.*系列的同名函数,换一个名字可能是为了更好的区别和理解。除了实现了对称加密算法外,EVP_Encrypt*.*系列还对块加密算法提供了缓冲功能。以后我们可能会更多使用EVP_Cipher的术语,因为它是真正的实现结构。EVP_Cipher*.*得以实现的一个基本结构是下面定义的一个算法结构,它定义了EVP_Cipher系列函数应该采用什么算法进行数据处理,其定义如下(evp.h):typedef struct evp_cipher_stint nid;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); /* Miscellaneous operations */void *app_data;EVP_CIPHER;下面对这个结构的部分成员的含义作一些解释:1. nid是算法类型的nid识别号,openssl里面每个对象都有一个内部唯一的识别ID2. block_size是每次加密的数据块的长度,以字节为单位3. key_len各种不同算法缺省的密钥长度4. iv_len初始化向量的长度5. init算法结构初始化函数,可以设置为加密模式还是解密模式6. do_cipher进行数据加密或解密的函数7. cleanup释放EVP_CIPHER_CTX结构里面的数据和设置。8. ctx_size设定ctx-cipher_data数据的长度9. set_asn1_parameters在EVP_CIPHER_CTX结构中通过参数设置一个ASN1_TYPE10. get_asn1_parameters从一个ASN1_TYPE中取得参数11. ctrl其它各种操作函数12. app_data应用数据通过定义这样一个指向这个结构的指针,你就可以在连接程序的时候只连接自己使用的算法;而如果你是通过一个整数来指明应该使用什么算法的话,会导致所有算法的代码都被连接到代码中。通过这样一个结构,还可以自己增加新的算法。在这个基础上,每个EVP_Cipher*.*函数都维护着一个指向一个EVP_CIPHER_CTX结构的指针。typedef struct evp_cipher_ctx_stconst EVP_CIPHER *cipher;ENGINE *engine;int encrypt;int buf_len;unsigned char oivEVP_MAX_IV_LENGTH;unsigned char ivEVP_MAX_IV_LENGTH;unsigned char bufEVP_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 finalEVP_MAX_BLOCK_LENGTH; EVP_CIPHER_CTX;下面对这个结构部分成员做简单的解释:1. cipher是该结构相关的一个EVP_CIPHER算法结构2. engine如果加密算法是ENGINE提供的,那么该成员保存了相关的函数接口3. encrypt加密或解密的标志4. buf_len该结构缓冲区里面当前的数据长度5. oiv初始的初始化向量6. iv工作时候使用的初始化向量7. buf保存下来的部分需要数据8. num在cfb/ofb模式的时候指定块长度9. app_data应用程序要处理数据10. key_len密钥长度,算法不一样长度也不一样11. cipher_data加密后的数据上述两个结构是EVP_Cipher(EVP_Encrypt)系列的两个基本结构,它们的其它一些列函数都是以这两个结构为基础实现了。文件evpevp_enc.c是最高层的封装实现,各种加密的算法的封装在p_enc.c里面实现,解密算法的封装在p_dec.c里面实现,而各个e_*.c文件则是真正实现了各种算法的加解密功能,当然它们其实也是一些封装函数,真正的算法实现在各个算法同名目录里面的文件实现。openssl对称加密算法的格式都以函数形式提供,其实该函数返回一个该算法的结构体,其形式一般如下:EVP_CIPHER* EVP_*(void)在openssl中,所有提供的对称加密算法长度都是固定的,有特别说明的除外。下面对这些算法进行分类的介绍,首先介绍一下算法中使用的通用标志的含义。通用标志:ecb电子密码本(Electronic Code Book)加密方式。cbc加密块链接(Cipher Block Chaining)加密方式。cfb64位加密反馈(Cipher Feedback)加密方式。ofb64位输出反馈(Output Feedback)加密方式。ede该加密算法采用了加密、解密、加密的方式,第一个密钥和最后一个密钥是相同的。ede3该加密算法采用了加密、解密、加密的方式,但是三个密钥都不相同。2.4.2 Openssl之摘要算法无论输入的消息有多长,计算出来的消息摘要的长度总是固定的。不同的输入会有不同的输出,而且输出的摘要消息可以通过随机性检验。一般地,只要输入的消息不同,对其进行摘要以后产生的摘要消息也必不相同;但相同的输入必会产生相同的输出。消息摘要函数是无陷门的单向函数,即只能进行正向的信息摘要,而无法从摘要中恢复出任何的消息,甚至根本就找不到任何与原信息相关的信息。无法找到两条消息,使它们的摘要相同。用途:数字签名技术。该系列函数封装了openssl加密库所有的信息摘要算法,通过这种EVP封装,当使用不同的信息摘要算法时,只需要对初始化参数修改一下就可以了,其它代码可以完全一样。这些算法包括MD2、MD5以及SHA等算法。EVP_MD结构介绍所有的算法都维护着下面定义的结构的一个指针,在此基础上实现了算法的功能。该结构EVP_MD如下:typedef struct env_md_stint type;int pkey_type;int md_size;unsigned long flags;int (*init)(EVP_MD_CTX *ctx);int (*update)(EVP_MD_CTX *ctx,const void *data,unsigned long count);int (*final)(EVP_MD_CTX *ctx,unsigned char *md);int (*copy)(EVP_MD_CTX *to,const EVP_MD_CTX *from);int (*cleanup)(EVP_MD_CTX *ctx);int (*sign)();int (*verify)();int required_pkey_type5; /*EVP_PKEY_xxx */int block_size;int ctx_size; EVP_MD;下面对该结构体的部分参数解释:type信息摘要算法的NID标识pkey_type-是信摘要-签名算法体制的相应NID标识,如NID_shaWithRSAEncryptionmd_size-是信息摘要算法生成的信息摘要的长度如SHA算法是SHA_DIGEST_LENGTH,该值是20init-指向一个特定信息摘要算法的初始化函数,如对于SHA算法,指针指向SHA_Initupdate-指向一个真正计算摘要值的函数,例如SHA算法就是指向SHA_Updatefinal-指向一个信息摘要值计算之后要调用的函数,该函数完成最后的一块数据的处理工作。例如SHA算法就是指向SHA_Final.Copy-指向一个可以在两个EVP_MD_CTX结构之间拷贝参数值的函数required_pkey_type-指向一个用来签名的算法EVP_PKEY的类型,如SHA算法就指向EVP_PKEY_RSA_methodblock_size-一个用来进行信息摘要的输入块的的长度(单位是字节),如SHA算法就是SHA_CBLOCKctx_size-是CTX结构的长度,在SHA算法里面应该就是sizeof(EVP_MD*)+sizeof(SHA_CTX)如果你要增加新的算法,那么可以定义这个结构,并进行必要的一直,然后就可以使用通用的函数了。跟EVP_CIPHER系列函数一样,使用这个封装技术,就可以在使用一种摘要算法时,比如MD5,在连接程序的时候就只连接MD5的代码。如果使用证书来标识算法,那么就会导致所有其它的信息摘要算法代码都连接到程序中去了。2.4.3 Openssl之公钥算法RSARSA算法是一个广泛使用的公钥算法。其密钥包括公钥和私钥。它能用于数字签名、身份认证以及密钥交换。RSA密钥长度一般使用1024位或者更高。RSA密钥信息主要包括: n:模数 e:公钥指数 d:私钥指数 p:最初的大素数 q:最初的大素数 dmp1:e*dmp1 = 1 (mod (p-1) dmq1:e*dmq1 = 1 (mod (q-1) iqmp:q*iqmp = 1 (mod p )其中,公钥为n和e;私钥为n和d。在实际应用中,公钥加密一般用来协商密钥;私钥加密一般用来签名。EVP_PKEY系列函数定义了一个密钥管理的结构体,其定义如下(opensslevp.h):typedef struct evp_pkey_stint type;int save_type;int references;unionchar *ptr;#ifndef OPENSSL_NO_RSAstruct rsa_st *rsa; /* RSA */#endif#ifndef OPENSSL_NO_DSAstruct dsa_st *dsa; /* DSA */#endif#ifndef OPENSSL_NO_DHstruct dh_st *dh; /* DH */#endif pkey;int save_parameters;STACK_OF(X509_ATTRIBUTE) *attributes; /* 0 */EVP_PKEY;该密钥结构既可以用来存储公钥,也可以用来存储私钥。该结构其实是一个在openssl中很通用的结构,在许多算法中使用了该结构作为存储体。2.5程序设计说明本节介绍程序具体的实现过程。2.5.1 文件操作模块本程序中的操作都是基于文件的操作,当你想使用本程序实现一个加密的时候,你需要首先导入文件并给这个文件的操作结果指定一个详细的路径,也就是输出文件了,结果将会保存在输出文件中。文件打开和保存分别应用了打开和保存对话框,即CfileDialog类中的相关方法。应用它只是为了给应用程序指定将要打开或保存的文件路径而已,读取文件和写入文件操作有fread和fwrite两个函数完成。C语言的标准库函数。程序中有涉及比较大的数据读取和写入,这里应用了循环读取与写入技术,配之于Openssl中的EVP_*Update函数可以实现循环读写操作。这样就基本解决了文件操作的问题。在RSA加密与解密的时候涉及到一个密钥对文件存储的问题,由于密钥文件的结构特殊,用一般的方式无法保存,本程序中运用了抽象IO实现基本的读写操作。openssl抽象IO(I/O abstraction,即BIO)是openssl对于io类型的抽象封装,包括:内存、文件、日志、标准输入输出、socket(TCP/UDP)、加/解密、摘要和ssl通道等。Openssl BIO通过回调函数为用户隐藏了底层实现细节,所有类型的bio的调用大体上是类似的。Bio中的数据能从一个BIO传送到另外一个BIO或者是应用程序。密钥文件以PEM格式保存,读取和写入都非常的方便,而且可靠性好。2.5.2 对称算法实现模块对称算法的实现需要调用EVP里的一些方法。考虑到EVP里的方法参数都非常的难于理解,我想到的是实现对称算法的方法是:我只需传入源文件、密文文件、和算法名称该模块就能帮我实现我想要的功能,所以我实现了一个封装方法对于对称加密解密的一个封装方法,用户只需传入需要加密的文件路径及输出路径、选择好加密算法设定好口令其他的程序就能顺利的完成了。Encrypt_File(CString strPlainFilePath, CString strCipherFilePath, int nAlg_ID, CString strPass)Decrypt_File(CString strCipherFilePath, CString strPlainFilePath, CString strPass)这两个函数的封装使得程序好理解多了。下面来说说对称算法的具体实现过程吧。1加密过程1. 打开输入输出文件并返回文件句柄。2. 初始化相关内容。cipher = EVP_get_cipherbynid(nAlg_ID);根据算法ID得到算法。3. EVP_BytesToKey()根据口令、密码算法生成key和iv。4. EVP_CIPHER_CTX_init(&ctx); 初始化ctx。5. EVP_EncryptInit_ex (&ctx,cipher,NULL,key,iv); 设置密码算法、key和iv6. 循环加密,以每次读取1024字节的大小循环读取文件并加密写入输出文件中。 EVP_EncryptUpdate(&ctx,out,&outl,in,inl);函数实现7. 加密结束。8. 释放相关资源。相关的参数类型名称描述unsigned charkeyEVP_MAX_KEY_LENGTH保存密钥的数组unsigned charivEVP_MAX_KEY_LENGTH保存初始化向量的数组EVP_CIPHER_CTXctxEVP加密上下文环境unsigned charout1024保存密文的缓冲区unsigned charin1024保存原文的缓冲区const EVP_CIPHER *cipher加密算法FILE *fpIn输入文件句柄FILE *fpOut输出文件句柄charenchead128=0保存密文文件头的数组表2-12解密过程解密过程与加密过程类似。1. 打开输入输出文件并返回文件句柄。2. 初始化相关内容。fread(enchead,1,128,fpIn); sscanf(enchead,ALGID:%dn,&nAlg_ID); 从文件中得到算法ID,根据算法ID得到算法。3. EVP_BytesToKey()根据口令、密码算法生成key和iv。4. EVP_CIPHER_CTX_init(&ctx); 初始化ctx。5. EVP_DecryptInit_ex (&ctx,cipher,NULL,key,iv); 设置密码算法、key和iv6. 循环加密,以每次读取1024字节的大小循环读取文件并解密写入输出文件中。 EVP_DecryptUpdate(&ctx,out,&outl,in,inl);函数实现7. 解密结束。8. 释放相关资源。2.5.3 摘要算法实现模块摘要算法是一个不可逆的计算过程,可以从一个A经过摘要到B但不能从B经过反摘要到A,所以它是一个无陷门的单向函数,这个模块设计过程中给了三个输入参数,输入文件和输出文件、摘要算法名称(没有根据算法ID来),在Openssl中获取目标算法的方法很多,你可以通过算法ID也可以通过算法名称获取目标算法。Digest_File(CString InFilePath, CString OutFilePath, CString nAlg_NAME)这个函数实现摘要算法。下面看看这个算法的具体实现过程类型名称描述EVP_MD_CTXmdctxEVP摘要上下文环境unsigned charout1024保存摘要后结果的缓冲区unsigned charin1024保存原文的缓冲区const EVP_MD *md摘要算法FILE *fpIn输入文件句柄FILE *fpOut输出文件句柄表2-2摘要过程:1. 打开输入输出文件并返回文件句柄。2. 初始化相关内容。md = EVP_get_digestbyname(nAlg_NAME);根据算法名称得到算法。3. EVP_MD_CTX_init(&mdctx);初始化摘要上下文参数。4. EVP_DigestInit_ex(&mdctx,md,NULL); 设置摘要算法的相关内容。5. 循环摘要,以每次读取1024字节的大小循环读取文件并摘要写入输出文件中。 EVP_DigestUpdate(&mdctx,in,inl);函数实现6. 摘要结束。7. 释放相关资源。2.5.4 RSA算法实现模块RSA算法实现过程是本次课程设计中最麻烦的一部分,由于RSA算法的特殊性,在读入原文时无法象对称和摘要算法那样每次读取1024字节,而是得根据RSA本身的加密算法来规定每次加密的数据块大小。RSA的密钥生成部分的密钥保存也是个棘手的问题,起初我想到的是用一般的文件存储私钥和公钥的数据即可,但这样完全不行,最后可以保存却无法还原成原来的私钥和公钥文件,后来运用抽象IO的文件操作解决这个问题。我将私钥和公钥的生成都直接放到可执行文件同一目录下,这样可能不好,但比较简捷的实现文件的读取和写入操作,我尽量让程序简单点,这样比较容易理解。所以对于密钥的路径这块我没太关注,只是随便的丢在主目录下。好了,来说说RSA的具体实现过程吧,我们先看看RSA实现的前期准备。上面提到的输入数据块大小的问题,得看选择的RSA加密及填充方法,下面列举了基本的几种对应的数据块长度。RSA_public_encrypt(flen,from,to,r,padding);这里的padding即填充方法各种padding 对输入数据长度的要求:私钥加密:RSA_PKCS1_PADDING RSA_size-11RSA_NO_PADDING RSA_size-0RSA_X931_PADDING RSA_size-2公钥加密RSA_PKCS1_PADDING RSA_size-11RSA_SSLV23_PADDING RSA_size-11RSA_X931_PADDING RSA_size-2RSA_NO_PADDING RSA_size-0RSA_PKCS1_OAEP_PADDING RSA_size-2 * SHA_DIGEST_LENGTH-2这里提到的RSA_size 可以通过RSA_size(r);函数获得,本程序中是128,而且我采用的是公钥加密私钥解密模式,选用的填充方式是RSA_PKCS1_PADDING 所以每次读入的数据块大小是(128-11)字节,及循环读入的数据块按每次读取117字节,加密后会填充到128字节,所以原文117对应密文128,解密的时候是密文128对应原文117,会去掉填充的11字节。为了方便使用我将实现RSA算法的一些方法整合到一个类中CMyRSA类该类中实现三个方法分别是:MakeKeys()RSAEncrypt(CString PlainFile, CString CipherFile, RSA *pubRSA)RSADecrypt(CString PlainFile, CString CipherFile, RSA *priRSA)MakeKeys()函数是实现密钥对的生成工作,当然如果你已经生成了密钥对,这个函数就可以不用调用了,公钥和私钥文件都是固定文件名的pub.pem和pri.pem 文件,所以你如果需要生成多个公钥和私钥文件的时候要记得移走已有的文件了,它们都会被放置在程序目录中,这些都是固定的,由于我想将程序简单化,没做太多的处理。好了现在我们有了公钥和私钥文件了,就可以开始进行加密了。加密过程:加密函数传入三个参数,输入输出和带有公钥信息的RSA结构体指针。1. 打开输入输出文件并返回文件句柄。2. 初始化相关内容。rsasize=RSA_size(pubRSA)-11;获取加密数据块长度。3. 循环加密,以每次读取117字节的大小循环读取文件并加密写入输出文件中。 RSA_public_encrypt(rsasize,in,out,pubRSA,RSA_PKCS1_PADDING);函数实现4.加密结束。5. 释放相关资源。解密过程:解密函数出入三个参数,输入输出和带有私钥信息的RSA结构体指针。1. 打开输入输出文件并返回文件句柄。2. 初始化相关内容。rsasize=RSA_size(pubRSA);获取解密数据块长度。3. 循环加密,以每次读取128字节的大小循环读取文件并解密写入输出文件中。 outl=RSA_private_decrypt(inl,in,out,priRSA,RSA_PKCS1_PADDING);函数实现4. 解密结束。5. 释放相关资源。在程序中会用到pubRSA和priRSA指针,这两个指针的获取是根据公钥文件和私钥文件得到的,利用抽象IO可实现对RSA结构体里的内容存储和读取。后面说明具体的方法。2.5.5 数字信封实现模块数字信封模块是对称和公钥算法的结合体,这个模块中选择的对称算法是DES公钥算法是RSA,其实这个模块的功能实现就是前面提到的对称和公钥方法,只是加密的对象有所不同而已,数字信封要求采用对称算法加密信息体,采用公钥算法加密对称算法中的密钥,实际上时为了方便数据传输,公钥文件是很容易获取的,并且它一般是公开的,你可获取对方的公钥然后利用数字信封技术给他传送机密文件,对方只能用他的私钥打开。公钥和私钥文件一般采用证书的形式,我这里没有采用证书,我将公钥和私钥文件已PEM格式的文件保存这个PEM文件采用了DES加密,相对而言还是有安全可言的。公钥和私钥文件在存储的时候都采用了BASED64编码。私钥文件实例:-BEGIN RSA PRIVATE KEY-Proc-Type: 4,ENCRYPTEDDEK-Info: DES-EDE3-OFB,1C91815ECA8FD0092p6glPtitT4Y65wGAX0LS0aPjJeGmWZHCBNvtaGJ21jkYImXEKgGHEufEwbCkSQZfVxEH1Q1a58zCM6EkykJRjcB7+b+9GtUnr043qBRUobxn78LyNW+f3wEo/D2UW1IiXFTa7gRcF9fIhgTtM11WkYiFKIWcz0Rcy0J0YKR0tD2gKXZLBrAE9FkqgDcItSPxfFKwbMv1E44qT0u+krRcceqn9SA6j/SWRxgjK5yCfJHAy+12XKzVGNpt5LU5C00l5c7n/l5HmsTYO64HeGfx7iR+LDmIIUNnte4T34Oi9dycNIN/8uOdQhOmSnqpdqDz3Y49ROUImIHWXpLFLegaVeDJWFatwNqmvVeTKejiBhVg/Y5cOmFoJMMvS5b12naraDkZcajeCHlThmysN9FxHQ3RE57b0WmJV9Edae4SgiCRaOjebzj0+2Lp9kvPlH7yzgT/JwzMr93TOGx6ZH2LwfmYmomFS2/1r15xmOwaV3d/Dwnq5VSQgWTQqoKPhdv8coHONanFOEqy9AGoMxNBApVeK2Irl606DNjmYV5ZT6VZ+5O9PerwRVS1pa8Aru4XRB5hhXb8Le5yvIJG9aPs80+W4tDZ0vEOVV9n999nxAvyygYjMcHHKsuBoZmZ93rwckprPJqV0l1gUHL1ee3LJpSbd/8OTsUrpYi1LVohGs908SvRGqahgT2K1QqpTwOEVvTUEbOhi4ns14zMgx7XR0z87jDMN/GQ3oABhGN+nqqyxtHF6McUthrvEpIBoNTe+tkQ7fupYSXMS47M1+Y5VeqkDi8DCkvQygpH7Is4w=-END RSA PRIVATE KEY-公钥文件实例:-BEGIN RSA PUBLIC KEY-MIGHAoGBALT04REg5f6XX1hzRc0QS+GRiwTljM7lQmXgIKGX1w6cLW8VEOtGt4yJ0wMYO33t9oaFY6WnIcHpcDa1JKgH+ljLGFHbRyZPZfj+4jue7RLTMV8t8o/BhsjgyUgXmsG36NX2J7k/3Shq+SqwGFbd9E+W3P/fYbCMXXHhLq01FToxAgED-END RSA PUBLIC KEY-上述两个文件是我即时生成的两个密钥文件。我设计的这个数字信封模块是完全基于文件的,数字信封采用Des加密后的密文和密钥加密后的结果存在于同一个文件中,解密的时候只需私钥文件即可,如果私钥文件时对的结果就可以解密出来。具体的实现过程与上述的基本相同。这里不累述了。我想在这里说说抽象IO存储公钥和私钥的方法。openssl抽象IO(I/O abstraction,即BIO)是openssl对于io类型的抽象封装,包括:内存、文件、日志、标准输入输出、socket(TCP/UDP)、加/解密、摘要和ssl通道等。Openssl BIO通过回调函数为用户隐藏了底层实现细节,所有类型的bio的调用大体上是类似的。Bio中的数据能从一个BIO传送到另外一个BIO或者是应用程序。密钥文件以PEM格式保存,读取和写入都非常的方便,而且可靠性好。/定义一个抽象IO实现对公钥和私钥的读取操作BIO *in;/RSA结构体,暂存公私钥信息。RSA *read;/加载Openssl所有的算法OpenSSL_add_all_algorithms();/读取公钥文件,并返回一个IO指针in=BIO_new_file(pub.pem,rb);read=RSA_new();/将公钥信息读入到RSA 结构中read=PEM_read_bio_RSAPublicKey(in,&read,NULL,123456);/读取公钥,公钥经过DES加密的,123456是解密口令。通过上述方法可以很方便的将

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论