实验目的
掌握各种对称算法接口的调用方法(C/C++方式)
掌握各种非对称算法接口的调用方法(C/C++方式)
掌握各种摘要算法接口的调用方法(C/C++方式)
实验原理
1.DES算法
des算法为密码体制中的对称密码体制,又被称为美国数据加密标准,是1972年美国IBM公司研制的对称密码体制加密算法。DES算法具有极高安全性,到目前为止,除了用穷举搜索法对DES算法进行攻击外,还没有发现更有效的办法。
2.AES运算
AES(The Advanced Encryption Standard)是美国国家标准与技术研究所用于加密电子数据的规范。它被预期能成为人们公认的加密包括金融、电信和政府数字信息的方法。该算法为比利时密码学家Joan Daemen和Vincent Rijmen所设计,结合两位作者的名字,以Rijndael之命名之,投稿高级加密标准的甄选流程。Rijdael的发音近于 "Rhinedoll,两位设计者的名字,参考荷兰语原发音可译为尤安•达蒙、文森特•莱蒙。(Joan不能译为女性化的名字"琼"。另外,西欧的姓名很多是有相同拉丁文或希腊文源头的,故译成中文是可能相同)
AES 是一个新的可以用于保护电子数据的加密算法。明确地说,AES 是一个迭代的、对称密钥分组的密码,它可以使用128、192 和 256 位密钥,并且用 128 位(16字节)分组加密和解密数据。与公共密钥密码使用密钥对不同,对称密钥密码使用相同的密钥加密和解密数据。通过分组密码返回的加密数据的位数与输入数据相同。迭代加密使用一个循环结构,在该循环中重复置换(permutations )和替换(substitutions)输入数据。
3.MD5原理概念
对MD5算法简要的叙述可以为:MD5以512位分组来处理输入的信息,且每一分组又被划分为16个32位子分组,经过了一系列的处理后,算法的输出由四个32位分组组成,将这四个32位分组级联后将生成一个128位散列值。
在MD5算法中,首先需要对信息进行填充,使其位长对512求余的结果等于448。因此,信息的位长(Bits Length)将被扩展至N512+448,N为一个非负整数,N可以是零。填充的方法如下,在信息的后面填充一个1和无数个0,直到满足上面的条件时才停止用0对信息的填充。然后,在这个结果后面附加一个以64位二进制表示的填充前信息长度。经过这两步的处理,信息的位长=N512+448+64= (N+1)*512,即长度恰好是512的整数倍。这样做的原因是为满足后面处理中对信息长度的要求。表示第i个分组,每次的运算都由前一轮的128位结果值和第i块512bit值进行运算。初始的128位值为初试链接变量,这些参数用于第一轮的运算,以大端字节序来表示,他们分别为:A=0x01234567,B=0x89ABCDEF,C=0xFEDCBA98,D=0x76543210。
4.SHA-1算法
SHA (Secure Hash Algorithm,译作安全散列算法) 是美国国家安全局 (NSA) 设计,美国国家标准与技术研究院 (NIST) 发布的一系列密码散列函数。正式名称为 SHA 的家族第一个成员发布于 1993年。然而现在的人们给它取了一个非正式的名称 SHA-0 以避免与它的后继者混淆。两年之后, SHA-1,第一个 SHA 的后继者发布了。 另外还有四种变体,曾经发布以提升输出的范围和变更一些细微设计: SHA-224, SHA-256, SHA-384 和 SHA-512 (这些有时候也被称做 SHA-2)。
5.RSA算法
RSA公开密钥密码体制。所谓的公开密钥密码体制就是使用不同的加密密钥与解密密钥,是一种“由已知加密密钥推导出解密密钥在计算上是不可行的”密码体制。非常好用。
在公开密钥密码体制中,加密密钥(即公开密钥)PK是公开信息,而解密密钥(即秘密密钥)SK是需要保密的。加密算法E和解密算法D也都是公开的。虽然秘密密钥SK是由公开密钥PK决定的,但却不能根据PK计算出SK。正是基于这种理论,1978年出现了著名的RSA算法,它通常是先生成一对RSA 密钥,其中之一是保密密钥,由用户保存;另一个为公开密钥,可对外公开,甚至可在网络服务器中注册。为提高保密强度,RSA密钥至少为500位长,一般推荐使用1024位。这就使加密的计算量很大。为减少计算量,在传送信息时,常采用传统加密方法与公开密钥加密方法相结合的方式,即信息采用改进的DES或IDEA对话密钥加密,然后使用RSA密钥加密对话密钥和信息摘要。对方收到信息后,用不同的密钥解密并可核对信息摘要。
RSA算法是第一个能同时用于加密和数字签名的算法,也易于理解和操作。RSA是被研究得最广泛的公钥算法,从提出到现在的三十多年里,经历了各种攻击的考验,逐渐为人们接受,普遍认为是目前最优秀的公钥方案之一。
6.DSA算法原理
数字签名是数据在公开行信道中传输的安全保障,能够实现数据公开、公正、不可抵赖等特点的方法,只能公开的密钥、密码签名算法。国际公认的公开密钥签字算法主要有RSA算法、EIGAMAL算法或者其变形的签名算法。DSA(Digite Signature Arithmotic)是Schnore和ElGamal算法的变型。
美国国家标准局(NIST)1994年5月19日公布了数字签名标准的(DSS),标准采用的是算法便是DSA,密钥长度为512-1024位。密钥长度俞长,签名速度愈慢,制约运算速度的主要因素是大数的模指数预算。
使用vc6.0++进行调试 代码如下
cryptAlgorithm.h头文件内容:
#ifndef __CRYPT_ALGORITHM_H
#define __CRYPT_ALGORITHM_H
#define CRYPT_SUCCESS 0
#define CRYPT_VERIFY_ERROR 10000
typedef void* RSAKey;
typedef void* DSAKey;
int AES128_ECB_encrypt(unsigned char *key,
unsigned char *input,
int inputLen,
unsigned char *output,
int *outputLen);
int AES128_ECB_decrypt(unsigned char *key,
unsigned char *input,
int inputLen,
unsigned char *output,
int *outputLen);
int AES128_CBC_encrypt(unsigned char *key,
unsigned char *iv,
unsigned char *input,
int inputLen,
unsigned char *output,
int *outputLen);
int AES128_CBC_decrypt(unsigned char *key,
unsigned char *iv,
unsigned char *input,
int inputLen,
unsigned char *output,
int *outputLen);
int DES_ECB_encrypt(unsigned char *key,
unsigned char *input,
int inputLen,
unsigned char *output,
int *outputLen);
int DES_ECB_decrypt(unsigned char *key,
unsigned char *input,
int inputLen,
unsigned char *output,
int *outputLen);
int DES_CBC_encrypt(unsigned char *key,
unsigned char *iv,
unsigned char *input,
int inputLen,
unsigned char *output,
int *outputLen);
int DES_CBC_decrypt(unsigned char *key,
unsigned char *iv,
unsigned char *input,
int inputLen,
unsigned char *output,
int *outputLen);
int MD5(unsigned char *input,
int inputLen,
unsigned char *output,
int *outputLen);
int SHA1(unsigned char *input,
int inputLen,
unsigned char *output,
int *outputLen);
int RSA1024_generateKey(RSAKey *key);
int RSA1024_freeKey(RSAKey *key);
int RSA1024_privateKeyEnc(RSAKey key,
unsigned char *input,
int inputLen,
unsigned char *output,
int *outputLen);
int RSA1024_privateKeyDec(RSAKey key,
unsigned char *input,
int inputLen,
unsigned char *output,
int *outputLen);
int RSA1024_publicKeyEnc(RSAKey key,
unsigned char *input,
int inputLen,
unsigned char *output,
int *outputLen);
int RSA1024_publicKeyDec(RSAKey key,
unsigned char *input,
int inputLen,
unsigned char *output,
int *outputLen);
int DSA_generateKey(DSAKey *key);
int DSA_freeKey(DSAKey key);
int DSA_dosign(DSAKey key,
unsigned char *dgst,
int dgstLen,
unsigned char *sig,
int *sigLen);
int DSA_doverify(DSAKey key,
unsigned char *dgst,
int dgstLen,
unsigned char *sig,
int sigLen);
#endif
test.cpp文件内容:
#include
#include "cryptAlgorithm.h"
static void hex_dump( const char *desc, unsigned char *data, int data_cb )
{
int i = 0;
if( desc ) {
printf( "%s, size=%d\n", desc, data_cb );
}
else {
printf( "size=%d\n", data_cb );
}
for( i =0; i0 && i%32 == 0 )
printf( "\n" );
printf( "%02X ", data[i] );
}
printf( "\n" );
}
void test_AES128_ECB()
{
unsigned char key[16] = { 0 };
unsigned char input[1008] = { 0 };
unsigned char output[1008] = { 0 };
int i;
int ret;
int len;
//初始化密钥
for(i=0; i<16; i++) {
key[i] = i;
}
//初始化明文输入
for(i=0; i<1008; i++) {
input[i] = i;
}
//加密
ret = AES128_ECB_encrypt(key, input, 1000, output, &len);
printf("AES128_ECB_encrypt return %d\n", ret);
hex_dump("AES128_ECB_encrypt results", output, len);
//解密
ret = AES128_ECB_decrypt(key, output, len, input, &len);
printf("AES128_ECB_decrypt return %d\n", ret);
hex_dump("AES128_ECB_decrypt results", input, len);
}
void test_AES128_CBC()
{
unsigned char key[16] = { 0 };
unsigned char iv[16] = { 0 };
unsigned char input[1008] = { 0 };
unsigned char output[1008] = { 0 };
int i;
int ret;
int len;
//初始化密钥
for(i=0; i<16; i++) {
key[i] = i;
}
//初始化IV向量,CBC模式必须要有IV
for(i=0; i<16; i++) {
iv[i] = i+100;
}
//初始化明文输入
for(i=0; i<1008; i++) {
input[i] = i;
}
//加密
ret = AES128_CBC_encrypt(key, iv, input, 1000, output, &len);
printf("AES128_CBC_encrypt return %d\n", ret);
hex_dump("AES128_CBC_encrypt results", output, len);
//解密
ret = AES128_CBC_decrypt(key, iv, output, len, input, &len);
printf("AES128_CBC_decrypt return %d\n", ret);
hex_dump("AES128_CBC_decrypt results", input, len);
}
void test_DES_ECB()
{
unsigned char key[8] = { 0 };
unsigned char input[1008] = { 0 };
unsigned char output[1008] = { 0 };
int i;
int ret;
int len;
//初始化密钥
for(i=0; i<8; i++) {
key[i] = i;
}
//初始化明文输入
for(i=0; i<1008; i++) {
input[i] = i;
}
//加密
ret = DES_ECB_encrypt(key, input, 1003, output, &len);
printf("DES_ECB_encrypt return %d\n", ret);
hex_dump("DES_ECB_encrypt results", output, len);
//解密
ret = DES_ECB_decrypt(key, output, len, input, &len);
printf("DES_ECB_decrypt return %d\n", ret);
hex_dump("DES_ECB_decrypt results", input, len);
}
void test_DES_CBC()
{
unsigned char key[8] = { 0 };
unsigned char iv[8] = { 0 };
unsigned char input[1008] = { 0 };
unsigned char output[1008] = { 0 };
int i;
int ret;
int len;
//初始化密钥
for(i=0; i<8; i++) {
key[i] = i;
}
//初始化IV向量,CBC加密模式必须要有IV向量
for(i=0; i<8; i++) {
iv[i] = i+100;
}
//初始化明文输入
for(i=0; i<1000; i++) {
input[i] = i;
}
//加密
//输入1003字节,加密时会自动做8字节补齐,输出应该是1008字节
//补齐时按照分组长度对齐,DES的分组长度是8字节
ret = DES_CBC_encrypt(key, iv, input, 1003, output, &len);
printf("DES_CBC_encrypt return %d\n", ret);
hex_dump("DES_CBC_encrypt results", output, len);
//解密
ret = DES_CBC_decrypt(key, iv, output, len, input, &len);
printf("DES_CBC_decrypt return %d\n", ret);
hex_dump("DES_CBC_decrypt results", input, len);
}
void test_MD5()
{
unsigned char input[1000] = { 0 };
unsigned char dgst[16] = { 0 }; //md5输出是16字节
int i;
int ret;
int len;
for(i=0; i<1000; i++) {
input[i] = i;
}
//计算md5摘要
ret = MD5(input, 1000, dgst, &len);
printf("MD5 return %d\n", ret);
hex_dump("MD5 results", dgst, len);
}
void test_SHA1()
{
unsigned char input[1000] = { 0 };
unsigned char dgst[20] = { 0 }; //sha1输出是20字节
int i;
int ret;
int len;
for(i=0; i<1000; i++) {
input[i] = i;
}
//计算sha1摘要
ret = SHA1(input, 1000, dgst, &len);
printf("SHA1 return %d\n", ret);
hex_dump("SHA1 results", dgst, len);
}
void test_RSA1024()
{
RSAKey key;
unsigned char input[128] = { 0 };
unsigned char output[128] = { 0 };
int i;
int ret;
int len;
for(i=0; i<128; i++) {
input[i] = i;
}
//生成RSA密钥对
RSA1024_generateKey(&key);
//私钥加密,输入必须小于密钥长度,即128字节
ret = RSA1024_privateKeyEnc(key, input, 100, output, &len);
printf("RSA1024_privateKeyEnc return %d\n", ret);
hex_dump("RSA1024_privateKeyEnc results", output, len);
//公钥解密
ret = RSA1024_publicKeyDec(key, output, len, input, &len);
printf("RSA1024_publicKeyDec return %d\n", ret);
hex_dump("RSA1024_publicKeyDec results", input, len);
//公钥加密,输入必须小于密钥长度,即128字节
ret = RSA1024_publicKeyEnc(key, input, 100, output, &len);
printf("RSA1024_publicKeyEnc return %d\n", ret);
hex_dump("RSA1024_publicKeyEnc results", output, len);
//私钥解密
ret = RSA1024_privateKeyDec(key, output, len, input, &len);
printf("RSA1024_privateKeyDec return %d\n", ret);
hex_dump("RSA1024_privateKeyDec results", input, len);
RSA1024_freeKey(key);
}
void test_DSA()
{
DSAKey key;
unsigned char input[1000] = { 0 };
unsigned char dgst[20] = { 0 };
unsigned char output[128] = { 0 };
int i;
int ret;
int dgstLen;
int sigLen;
for(i=0; i<1000; i++) {
input[i] = i;
}
//签名时先做摘要
ret = SHA1(input, 1000, dgst, &dgstLen);
printf("SHA1 return %d\n", ret);
hex_dump("SHA1 results", dgst, dgstLen);
//生成DSA密钥对
DSA_generateKey(&key);
//DSA签名
ret = DSA_dosign(key, dgst, dgstLen, output, &sigLen);
printf("DSA_dosign return %d\n", ret);
hex_dump("DSA_dosign results", output, sigLen);
//修改签名值,再去验证签名,肯定会验证失败
// output[10] = 1;
//DSA验签
ret = DSA_doverify(key, dgst, dgstLen, output, sigLen);
printf("DSA_doverify return %d\n", ret);
if( ret == CRYPT_SUCCESS ) {
printf("verify OK\n");
}
else {
printf("verify FAIL\n");
}
DSA_freeKey(key);
}
void main()
{
// test_AES128_ECB();
// test_AES128_CBC();
// test_DES_ECB();
// test_DES_CBC();
// test_MD5();
// test_SHA1();
// test_RSA1024();
test_DSA();
}
运行结果如下 测出ECB,MD5,SHA1(),DSA等加密算法的长度和相关加密实现过程:
加密解密真j儿难。。。。都是Algorithm
继续刷网技视频去了。。爱好只能是爱好而已。。。