首页
社区
课程
招聘
[旧帖] [原创]RSA演示程序 0.00雪花
发表于: 2011-1-20 12:50 1446

[旧帖] [原创]RSA演示程序 0.00雪花

2011-1-20 12:50
1446
初学加解密,看了RSA的原理觉得抽象,就自己写了个Demo,拿出来晒晒

/*---------------------------------------------------------------------
//File name : RSASimulation.cpp
//Coder : rainday163
//E-mail : rainday163@163.com
//Create date : 2011.1.18
//Last modify date : 2011.1.20
//Test platform : Windows XP SP3 && VC 6.0
------------------------------------------------------------------------*/

#include <stdio.h>

const unsigned long p=13;
const unsigned long q=23;
const unsigned long n=p*q;
const unsigned long e=5;
const unsigned long d=53;

/*
public key  : (e,n) = (5,299)
private key : (d,n) = (53,299)
*/

short encryptChar(char c)                //Public key encrypt
{
        short m=c;
        int i=0;
        unsigned long temp=1;
        while (i++ < e)
        {
                temp *= m;
                temp %= n;
        }
        return (short)temp;
}

char decryptChar(short m)                //Private key decrypt
{
        int i=0;
        int temp=1;
        while (i++ < d)
        {
                temp *= m;
                temp %= n;
        }
        return (char)temp;
}

int main()
{
        char c;
        short r=0;
        int i=0;

        for(i=0;i<128;++i)        //Char test
        {
                c=i;
                r=encryptChar(c);        //Encrypt with RSA public key
                printf("%d\t",r);
                c=0;
                c=decryptChar(r);   //Decrypt with RSA private key
                printf("%d : %c\n",c,c);
        }

        return 0;
}

说明:
上面的代码只是在保证不溢出的情况下写的测试代码,主要是帮助理解算法。

附(这个是从网上找的):
用两个很大的质数,p 和 q,计算它们的乘积 n = pq;n 是模数。选择一个比 n 小的数 e,它与 (p - 1)(q - 1) 互为质数,即,除了 1 以外,e 和 (p - 1)(q - 1) 没有其它的公因数。找到另一个数 d,使 (ed - 1) 能被 (p - 1)(q - 1) 整除。值 e 和 d 分别称为公共指数和私有指数。公钥是这一对数 (n, e);私钥是这一对数 (n, d)。

[课程]FART 脱壳王!加量不加价!FART作者讲授!

上传的附件:
收藏
免费 0
支持
分享
最新回复 (2)
雪    币: 46
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
下面这个是借助Openssl实现的RSA加解密的demo:
测试环境:Windows Xp SP3 + VC6

#include <openssl/pem.h>
#include <openssl/evp.h>
#include <stdio.h>
#include <string.h>

#pragma comment(lib,"libeay32.lib")
#pragma comment(linker,"/force:multiple")

const int bits=1024;

bool  RSAPrivateEncrypt(RSA *r, int padding, unsigned char *from, unsigned char *to)
{
        int flen=0,len=0;
        if (NULL == r || NULL == from || NULL == to)
                return false;
        flen = RSA_size(r);

        if(padding==RSA_PKCS1_PADDING)
                flen-=11;
        else if(padding==RSA_X931_PADDING)
                flen-=2;
        else if(padding==RSA_NO_PADDING)
                flen=flen;

        len = RSA_private_encrypt(flen,from,to,r,padding);       
        if(len <= 0)
                return false;
        return true;
}

bool  RSAPublicDecrypt(RSA *r, int padding, unsigned char *from, unsigned char *to)
{
        int flen=0,len=0;
        if (NULL == r || NULL == from || NULL == to)
                return false;
        flen = RSA_size(r);
        len=RSA_public_decrypt(flen,from,to,r,padding);
        if(len <= 0)
                return false;
        return true;
}

bool  RSAPrivateEncryptPKCS1(RSA *r, unsigned char *from, unsigned char *to)
{
        return RSAPrivateEncrypt(r,RSA_PKCS1_PADDING,from,to);
}

bool  RSAPublicDecryptPKCS1(RSA *r, unsigned char *from, unsigned char *to)
{
        return RSAPublicDecrypt(r,RSA_PKCS1_PADDING,from,to);
}

int GenerateRSAKeyFiles()
{
        int  ret;
        BIGNUM *bne;
        BIO *out;
        RSA *r;
        unsigned long e=RSA_3;
        const EVP_CIPHER *enc=NULL;
        bne=BN_new();
        ret=BN_set_word(bne,e);
        if(ret != 1)
                return false;
        r = RSA_new();
        ret=RSA_generate_key_ex(r,bits,bne,NULL);
        if (ret != 1)
        {
                printf("RSA_generate_key_ex err!\n");
                return -1;
        }
        BN_free(bne);

        out = BIO_new_file("pri.pem","wb");
        ret = PEM_write_bio_RSAPrivateKey(out,r,enc,NULL,0,NULL,NULL);
        if (ret != 1)
        {
                RSA_free(r);
                BIO_free(out);
                return -1;
        }
        BIO_flush(out);
        BIO_free(out);
        out = BIO_new_file("pub.pem","wb");
        ret = PEM_write_bio_RSAPublicKey(out,r);
        if (ret != 1)
        {
                RSA_free(r);
                BIO_free(out);
                return -1;
        }
        BIO_flush(out);
        BIO_free(out);
        return 0;
}

bool getPriKey(RSA** r)
{       
        BIO *in =NULL;
        if(NULL == r)
                return false;
        if(NULL == (in = BIO_new_file("pri.pem","rb")))
                return false;
        *r = PEM_read_bio_RSAPrivateKey(in,r,NULL,NULL);
        if (NULL == (*r)->d)
                return false;
        BIO_free(in);
        return true;
}

bool getPubKey(RSA** r)
{
        BIO *in = NULL;
        if(NULL == r)
                return false;
        if( NULL == (in = BIO_new_file("pub.pem","rb")))
                return false;
        *r = PEM_read_bio_RSAPublicKey(in,r,NULL,NULL);
        if (NULL == (*r)->e)
                return false;
        BIO_free(in);
        return true;
}

int testPKCS1()
{
        RSA  *r;
        unsigned char from[1000]={0},to[1000]={0},out[1000]={0};

        memcpy(from,"pksc1",6);

        GenerateRSAKeyFiles();
        r=RSA_new();

        if(!getPriKey(&r))
                return -1;

        if (!RSAPrivateEncryptPKCS1(r,from,to))
        {
                printf("Private encrypt fail!\r\n");
                return -1;
        }
        RSA_free(r);

        r=RSA_new();
        if(!getPubKey(&r))
                return -1;
        if (!RSAPublicDecryptPKCS1(r,to,out))
        {
                printf("Public decrypt fail!\r\n");
                return -1;
        }
        printf("decrypt : %s\n",out);
        RSA_free(r);
        return 0;
}

int main()
{
        testPKCS1();
        return 0;
}
2011-1-20 22:35
0
雪    币: 284
活跃值: (16)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
有没有实际用途的不是用来加文件上的捏?
2011-1-21 08:36
0
游客
登录 | 注册 方可回帖
返回
//