zoukankan      html  css  js  c++  java
  • 加密算法代码实践

    实验目的

    掌握各种对称算法接口的调用方法(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
    ", desc, data_cb );
    
        }
    
        else {
    
            printf( "size=%d
    ", data_cb );
    
        }
    
    
    
        for( i =0; i<data_cb; i++ ) {
    
            if( i>0 && i%32 == 0 )
    
                printf( "
    " );
    
    
    
            printf( "%02X ", data[i] );
    
        }
    
    
    
        printf( "
    " );
    
    }
    
    
    
    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
    ", ret);
    
        hex_dump("AES128_ECB_encrypt results", output, len);
    
    
    
        //解密
    
        ret = AES128_ECB_decrypt(key, output, len, input, &len);
    
        printf("AES128_ECB_decrypt return %d
    ", 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
    ", 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
    ", 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
    ", ret);
    
        hex_dump("DES_ECB_encrypt results", output, len);
    
    
    
        //解密
    
        ret = DES_ECB_decrypt(key, output, len, input, &len);
    
        printf("DES_ECB_decrypt return %d
    ", 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
    ", 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
    ", 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
    ", 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
    ", 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
    ", ret);
    
        hex_dump("RSA1024_privateKeyEnc results", output, len);
    
    
    
        //公钥解密
    
        ret = RSA1024_publicKeyDec(key, output, len, input, &len);
    
        printf("RSA1024_publicKeyDec return %d
    ", ret);
    
        hex_dump("RSA1024_publicKeyDec results", input, len);
    
    
    
        //公钥加密,输入必须小于密钥长度,即128字节
    
        ret = RSA1024_publicKeyEnc(key, input, 100, output, &len);
    
        printf("RSA1024_publicKeyEnc return %d
    ", ret);
    
        hex_dump("RSA1024_publicKeyEnc results", output, len);
    
    
    
        //私钥解密
    
        ret = RSA1024_privateKeyDec(key, output, len, input, &len);
    
        printf("RSA1024_privateKeyDec return %d
    ", 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
    ", 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
    ", 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
    ", ret);
    
        if( ret == CRYPT_SUCCESS ) {
    
            printf("verify OK
    ");
    
        }
    
        else {
    
            printf("verify FAIL
    ");
    
        }
    
    
    
        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

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

  • 相关阅读:
    C++ 黑白棋AI minimax+alphabeta剪枝
    BZOJ2839 集合计数 容斥
    BZOJ2287 消失之物
    CF235B Let's Play Osu! 期望DP
    线性基
    [HAOI2008]糖果传递 结论题
    [HAOI2007]上升序列
    线性筛及线性递推欧拉函数
    Codeforces 1064D/1063B Labyrinth
    洛谷P2120 [ZJOI2007]仓库建设 斜率优化DP
  • 原文地址:https://www.cnblogs.com/whatiwhere/p/8722239.html
Copyright © 2011-2022 走看看