各种加密算法编程演示实验

实验目的

掌握各种对称算法接口的调用方法(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 <stdio.h>

#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; i<data_cb; i++ ) {

        if( i>0 && 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等加密算法的长度和相关加密实现过程:

Snipaste_2018-04-05_13-26-16.jpg

加密解密真j儿难。。。。都是Algorithm

继续刷网技视频去了。。爱好只能是爱好而已。。。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,634评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,951评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,427评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,770评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,835评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,799评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,768评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,544评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,979评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,271评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,427评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,121评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,756评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,375评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,579评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,410评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,315评论 2 352