RSA

RSA加密原理详解,以及RSA中的数论基础 RSA加密是一种非对称加密算法,由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)在1977年首次公开提出。RSA是他们三人姓氏的首字母组成的。RSA算法基于一个数学上的事实:将两个大质数相乘很容易,但是想要将其乘积分解成原始的质数因子却非常困难。这就是所谓的“陷门函数TDF”的概念,是RSA加密安全性的基础。本文将举例讲解RSA的加解密流程和相关数论基础 阅读详情
#include
#include

using namespace std;
typedef struct  RSA_PARAM_Tag
{
    unsigned __int64    p, q;   //两个素数,不参与加密解密运算
    unsigned __int64    f;      //f=(p-1)*(q-1),不参与加密解密运算
    unsigned __int64    n, e;   //公匙,n=p*q,gcd(e,f)=1
    unsigned __int64    d;      //私匙,e*d=1 (mod f),gcd(n,d)=1
} RSA_PARAM;//小素数表
const static long    g_PrimeTable[]=
{
    3,
    5,
    7,
    11,
    13,
    17,
    19,
    23,
    29,
    31,
    37,
    41,
    43,
    47,
    53,
    59,
    61,
    67,
    71,
    73,
    79,
    83,
    89,
    97
};
const static long       g_PrimeCount=sizeof(g_PrimeTable) / sizeof(long);
const unsigned __int64  multiplier=12747293821LL;
const unsigned __int64  adder=1343545677842234541LL;//随机数类
class                   RandNumber
{
private:
    unsigned __int64    randSeed;
public:
    RandNumber(unsigned __int64 s=0);
    unsigned __int64    Random(unsigned __int64 n);
};
RandNumber::RandNumber(unsigned __int64 s)
{
    if(!s)
    {
        randSeed= (unsigned __int64)time(NULL);
    }
    else
    {
        randSeed=s;
    }
}
unsigned __int64 RandNumber::Random(unsigned __int64 n)
{
    randSeed=multiplier * randSeed + adder;
    return randSeed % n;
}static RandNumber   g_Rnd;
inline unsigned __int64 MulMod(unsigned __int64 a, unsigned __int64 b, unsigned __int64 n)
{
    return a * b % n;
}
unsigned __int64 PowMod(unsigned __int64 base, unsigned __int64 pow, unsigned __int64 &n)
{
    unsigned __int64    a=base, b=pow, c=1;
    while(b)
    {
        while(!(b & 1))
        {
            b>>=1;            //a=a * a % n;    //函数看起来可以处理64位的整数,但由于这里a*a在a>=2^32时已经造成了溢出,因此实际处理范围没有64位
            a=MulMod(a, a, n);
        }        b--;        //c=a * c % n;        //这里也会溢出,若把64位整数拆为两个32位整数不知是否可以解决这个问题。
        c=MulMod(a, c, n);
    }    return c;
}

long RabinMillerKnl(unsigned __int64 &n)
{
    unsigned __int64    b, m, j, v, i;
    m=n - 1;
    j=0;    //0、先计算出m、j,使得n-1=m*2^j,其中m是正奇数,j是非负整数
    while(!(m & 1))
    {
        ++j;
        m>>=1;
    }    //1、随机取一个b,2<=b
    b=2 + g_Rnd.Random(n - 3);    //2、计算v=b^m mod n
    v=PowMod(b, m, n);    //3、如果v==1,通过测试
    if(v == 1)
    {
        return 1;
    }    //4、令i=1
    i=1;    //5、如果v=n-1,通过测试
    while(v != n - 1)
    {
        //6、如果i==l,非素数,结束
        if(i == j)
        {
            return 0;
        }        //7、v=v^2 mod n,i=i+1
        v=PowMod(v, 2, n);
        ++i;        //8、循环到5
    }    return 1;
}
long RabinMiller(unsigned __int64 &n, long loop)
{
    //先用小素数筛选一次,提高效率
    for(long i=0; i < g_PrimeCount; i++)
    {
        if(n % g_PrimeTable[i] == 0)
        {
            return 0;
        }
    }    //循环调用Rabin-Miller测试loop次,使得非素数通过测试的概率降为(1/4)^loop
    for(long i=0; i < loop; i++)
    {
        if(!RabinMillerKnl(n))
        {
            return 0;
        }
    }    return 1;
}
unsigned __int64 RandomPrime(char bits)
{
    unsigned __int64    base;
    do
    {
        base= (unsigned long)1 << (bits - 1);   //保证最高位是1
        base+=g_Rnd.Random(base);               //再加上一个随机数
        base|=1;    //保证最低位是1,即保证是奇数
    } while(!RabinMiller(base, 30));    //进行拉宾-米勒测试30次
    return base;    //全部通过认为是素数
}
unsigned __int64 EuclidGcd(unsigned __int64 &p, unsigned __int64 &q)
{
    unsigned __int64    a=p > q ? p : q;
    unsigned __int64    b=p < q ? p : q;
    unsigned __int64    t;
    if(p == q)
    {
        return p;   //两数相等,最大公约数就是本身
    }
    else
    {
        while(b)    //辗转相除法,gcd(a,b)=gcd(b,a-qb)
        {
            a=a % b;
            t=a;
            a=b;
            b=t;
        }        return a;
    }
}
unsigned __int64 SteinGcd(unsigned __int64 &p, unsigned __int64 &q)
{
    unsigned __int64    a=p > q ? p : q;
    unsigned __int64    b=p < q ? p : q;
    unsigned __int64    t, r=1;
    if(p == q)
    {
        return p;           //两数相等,最大公约数就是本身
    }
    else
    {
        while((!(a & 1)) && (!(b & 1)))
        {
            r<<=1;          //a、b均为偶数时,gcd(a,b)=2*gcd(a/2,b/2)
            a>>=1;
            b>>=1;
        }        if(!(a & 1))
        {
            t=a;            //如果a为偶数,交换a,b
            a=b;
            b=t;
        }        do
        {
            while(!(b & 1))
            {
                b>>=1;      //b为偶数,a为奇数时,gcd(b,a)=gcd(b/2,a)
            }            if(b < a)
            {
                t=a;        //如果b小于a,交换a,b
                a=b;
                b=t;
            }            b=(b - a) >> 1; //b、a都是奇数,gcd(b,a)=gcd((b-a)/2,a)
        } while(b);
        return r * a;
    }
}
unsigned __int64 Euclid(unsigned __int64 &a, unsigned __int64 &b)
{
    unsigned __int64    m, e, i, j, x, y;
    long                xx, yy;
    m=b;
    e=a;
    x=0;
    y=1;
    xx=1;
    yy=1;
    while(e)
    {
        i=m / e;
        j=m % e;
        m=e;
        e=j;
        j=y;
        y*=i;
        if(xx == yy)
        {
            if(x > y)
            {
                y=x - y;
            }
            else
            {
                y-=x;
                yy=0;
            }
        }
        else
        {
            y+=x;
            xx=1 - xx;
            yy=1 - yy;
        }        x=j;
    }    if(xx == 0)
    {
        x=b - x;
    }    return x;
}
RSA_PARAM RsaGetParam(void)
{
    RSA_PARAM           Rsa={ 0 };
    unsigned __int64    t;
    Rsa.p=RandomPrime(16);          //随机生成两个素数
    Rsa.q=RandomPrime(16);
    Rsa.n=Rsa.p * Rsa.q;
    Rsa.f=(Rsa.p - 1) * (Rsa.q - 1);
    do
    {
        Rsa.e=g_Rnd.Random(65536);  //小于2^16,65536=2^16
        Rsa.e|=1;                   //保证最低位是1,即保证是奇数,因f一定是偶数,要互素,只能是奇数
    } while(SteinGcd(Rsa.e, Rsa.f) != 1);    Rsa.d=Euclid(Rsa.e, Rsa.f);
return Rsa;
}



int main(void)
{
    RSA_PARAM  r;
    char  pSrc[5];
    const unsigned long n=sizeof(pSrc);
    unsigned char  *q, pDec[n];
    unsigned __int64  pEnc[n];
    r=RsaGetParam();
    cout << "p=" << r.p << endl;
    cout << "q=" << r.q << endl;
    cout << "f=(p-1)*(q-1)=" << r.f << endl;
    cout << "n=p*q=" << r.n << endl;
    cout << "e=" << r.e << endl;
    cout << "d=" << r.d << endl;
    cout << endl<<"请输入明文:";
cin>> pSrc;
    q= (unsigned char *)pSrc;
    cout << endl<<"加密(密文):";
    for(unsigned long i=0; i < n; i++)
    {
        pEnc[i]=PowMod(q[i], r.e, r.n);
        cout << hex << pEnc[i] << " ";
    }
cout << endl<<endl;
    //cout << "解密:";
    for(unsigned long i=0; i < n; i++)
    {
        pDec[i]=PowMod(pEnc[i], r.d, r.n);
        //cout << hex << (unsigned long)pDec[i] << " ";
    }
cout << "明文:"<<(char *)pDec<<endl<<endl;
    return 0;
}

RSA之基于hutool的快速实现 刚刚临时帮同事写个rsa加密的工具包,基于hutool的快速实现,随手给需要的小朋友, 非依赖hutool的请看我另外的文章,RSA加密算法Java应用解析-目前地球上最有影响力的加密算法 RSA工具包 2020年08月02日21:06:42 关于RSA就不多说了,直接上干货 一、首先获取公私钥 // 第一次使用时获取,获取后保存公私钥,不要重复获取 Map<String, String> stringStringMap = RsaUtils.generateKeyPair(); . 阅读详情

相关推荐

RSA默认填充方式说明

为什么80%的码农都做不了架构师?>>> ...

weixin_34284188的博客 4460

RSA密码

RSA就是公钥加密的经典。这个主要是基于大整数的素数分解问题,这个难题的。大概过程是这样的,首先,产生二个大素数p,q.然后计算n=p*q,则f=(p-1)*(q-1),然后,我们在&lt;n中寻找一个数e,是的gcd(e,f)=1,gcd()函数就是求解最大公约数的函数,也就是e和f互素。这样,根据扩展的欧几里得算法,可以知道x*e+y*f=1,这个中的x=d,也就是d*e mod f=1,假如...

daydayup_666的博客 677

RSA详解

RSA详解 最近在复习计算机安全的内容,发现网上关于RSA算法的讲解都不够详细,所以自己写一篇。 RSA算法是一个常用的公钥加密算法。 所谓的公钥加密就是用两个密钥,一个公钥一个私钥。通常来说,加密是用的公钥,解密用的私钥。而这两个密钥都是接收方的。 要理解公钥加密的优越性首先要看看对称密码的缺陷。所谓的对称加密呢就是用一个密钥来加密解密。这个时候发送方用密钥加密完了,要想办法把密钥发给接收方...

StephenArk的博客 1337

Rabin-Miller素数测试与RSA算法简介

RSA算法??? 1978年就出现了这种算法,它是第一个既能用于数据加密也能用于数字签名的算法。它易于理解和操作,也很流行。算法的名字以发明者的名字命名:Ron Rivest, AdiShamir 和Leonard Adleman。但RSA的安全性一直未能得到理论上的证明。??? RSA的安全性依赖于大数难于分解这一特点。公钥和私钥都是两个大素数(大于100个十进制位)的函数。据猜测,从一个密钥和

4622

RSA算法知识点速记

再次学习 RSA 算法,知识点速记: 将 n 和 e 封装成公钥,n 和 d 封装成私钥 p 和 q 是大质数,n = p*q e 一般取值65537 d 是 e 对于 φ(n) 的模反元素,即 ed ≡ 1 (mod φ(n)) 所以,公钥 ( n , e ),私钥 ( n , d )中,n、e是公开的,d 是私有的。 d 的值在生成私钥的时候就确定了,但以为其值是方程 ed - 1 = k...

JoshuaJ的专栏 1060

rsa加解密的内容超长的问题解决

一. 现象:      有一段老代码用来加密的,但是在使用key A的时候,抛出了异常:javax.crypto.IllegalBlockSizeException: Data must not be longer than 117 bytes。老代码已经做了分段的加密,应该是已经考虑了加密长度的问题才对。换了另一个线上代码中的key B,正常加密没有异常。 二. 解决:    

taoxin52的专栏 4万+

RSA密码的C++实现

//RSA密码 /*理解算法最重要,最好自己动手实现试试看,可以使用MFC写一个简单的交互界面*/ #include #include #include #include using namespace std; //RSA算法所需参数 typedef struct RSA_PARAM_Tag { unsigned __int64 p, q; //两个素数,不参与加密

-CQ-的专栏 3616

RSA算法

RSA算法 RSA加密算法是一种非对称加密算法。在公开密钥加密和电子商业中RSA被广泛使用。 RSA原理: RSA算法基于一个十分简单的数论事实:将两个大素数相乘十分容易,但是想要对其乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥。通常是先生成一对RSA 密钥,其中之一是保密密钥,由用户保存;另一个为公开密钥,可对外公开,甚至可在网络服务器中注册。为提高保密强度,RSA密钥至少为500...

且视他人之疑目如盏盏鬼火,大胆地去走你的夜路 1万+

RSA】加密算法 RSA| RSA_pss| RSA_oaep 讲解与使用示例

RSA-PSS 和 RSA-OAEP是 RSA算法的改进版本,它们通过使用更安全的填充方案来提高算法的安全性,但牺牲了一些性能。RSA算法、RSA-PSS和RSA-OAEP都是基于RSA加密算法构建的,但它们用于不同的目的,并具有一些关键的区别。RSA-OAEP 是一种概率性加密方案,这意味着即使使用相同的密钥对相同的明文进行多次加密,每次产生的密文也是不同的。请注意,RSA加密通常用于加密小量的数据,如密钥交换中的对称密钥,而不是大量数据,因为 RSA加密和解密操作相对较慢。

Young_Pro的博客 4405

BUUCTF — RSA1、RSA2、RSA3

BUUCTF中RSA系列题解

2401_88678276的博客 1877

RSA加密 — 详解

文章目录RSA 简介实际运用注意事项实战 RSA 简介 RSA——非对称加密,会产生公钥和私钥,公钥在客户端,私钥在服务端。公钥用于加密,私钥用于解密。 实际运用注意事项 1、一般由服务器创建秘钥对,私钥保存在服务器,公钥下发至客户端 2、公钥是二进制数据,怎么下发给客户端呢? 第一种方式:服务器把二进制数据写入文件,然后把文件传给客户端。由客户端从文件读取二进制数据。 第二种方式:服务器把二进制数据转成 base64 字符串,客户端获取到 base64 字符串后,再转码为二进制数据。 实战 我们封存一

赵彦军 2万+

RSA介绍

一 什么是RSA RSA是一种公钥密码算法,它的名字由三位开发者,即Ron Rivest、Adi Shamir和Leonard Adleman的姓氏的首字母组成的。 RSA被用于公钥密码和数字签名。 1983年,RSA公司为RSA算法在美国取得了专利,但现在该专利已经过期。 二 RSA加密 在RSA中,明文、密钥和密文都是数字。RSA的加密过程可以用下面的公式来表达。 RSA的密文...

实践求真知 7万+

OpenSSL库的RSA使用(下)-rsa函数方式

本文上接:OpenSSL库的RSA使用(上)-EVP方式,URL:http://blog.csdn.net/fenghaibo00/article/details/17248381 3      RSA函数方式 3.1 步骤 i.             生成RSA的key,包括三部分:公钥指数、私钥指数和模数(这些需要先了解一下RSA算法的原理) ii.           

Leo的专栏 4万+

RSA算法原理及Rsa-Tools

The RSA encryption algorithm is an asymmetric encryption algorithm. RSA is widely used in public key cryptography and electronic commerce. RSA was proposed in 1977 by Ron Rivest, Adi Shamir, and Leon...

qq_45521281的博客 2370

RSA 加密和 RSA 数字签名

RSA 加密和 RSA 数字签名是 RSA 算法的两种主要应用,它们都基于非对称密钥对和模幂运算,但在目的、密钥使用方向、操作对象以及提供的安全服务上存在显著差异。加密提供机密性,而签名提供真实性、完整性和不可否认性。在实际应用中,它们经常结合使用以提供更全面的安全保障。这样做可以同时实现机密性(只有接收方能读)和身份认证/完整性(接收方能确认消息来源和未被篡改)。是的,可以对同一条消息先进行签名,再进行加密(通常是先签名,然后将消息和签名一起加密)。

weixin_49342084的博客 1433

RSA算法的填充模式

一. 简介 RSA算法的常见的表现模式是多少位,例如1024、2048、4096等,这些并不是公钥或私钥的位数,而是模长。先简单介绍下RSA算法的密钥生成过程: 给定两个大素数p、q,令 n = p*q; 给定一个数e,使得e和φ(n)互质,则存在d,使得 e*d = 1 (mod φ(n)),d即是e对同余数φ(n)的模反元素; 以上的 e,d分别是公钥和私钥,给出的通常会带有n,如公钥是(e, n),私钥是(d, n)。 加解密过程,给定明文数字M(< n,加密时通常是字符串,转成大整数即可),

Denny_Chen_的博客 7417

RSA公钥密码总结

RSA公钥密码相关总结

chlet的博客 1万+

OpenSSL之RSA用法

RSA公开密钥密码体制是一种使用不同的加密密钥与解密密钥,“由已知加密密钥推导出解密密钥在计算上是不可行的”密码体制。在公开密钥密码体制中,加密密钥(即公开密钥)PK是公开信息,而解密密钥(即秘密密钥)SK是需要保密的。加密算法E和解密算法D也都是公开的。虽然解密密钥SK是由公开密钥PK决定的,但却不能根据PK计算出SK。正是基于这种理论,1978年出现了著名的RSA算法,它通常是先生成一对RSA密钥,其中之一是保密密钥,由用户保存;另一个为公开密钥,可对外公开,甚至可在网络服务器中注册。

史D芬周 6497
上一篇: MD5
下一篇: EFS加密破解
龍城狂霸拽爺
博客等级 码龄16年 10粉丝 101原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值