⑴ 电脑RSA是加密的那里怎么找到
1,电脑上的RSA加密是一种公开密钥密码体制。所谓的公开密钥密码体制就是使用不同的加密密钥与解密密钥,是一种“由已知加密密钥推导出解密密钥在计算上是不可行的”密码体制。
2,在公开密钥密码体制中,加密密钥(即公开密钥)PK是公开信息,而解密密钥(即秘密密钥)SK是需要保密的。加密算法E和解密算法D也都是公开的。虽然解密密钥SK是由公开密钥PK决定的,但却不能根据PK计算出SK。
3,正是基于这种理论,1978年出现了着名的RSA算法,它通常是先生成一对RSA 密钥,其中之一是保密密钥,由用户保存;另一个为公开密钥,可对外公开,甚至可在网络服务器中注册。为提高保密强度,RSA密钥至少为500位长,一般推荐使用1024位。这就使加密的计算量很大。
4,RSA算法是第一个能同时用于加密和数字签名的算法,也易于理解和操作。RSA是被研究得最广泛的公钥算法,从提出到现今的三十多年里,经历了各种攻击的考验,逐渐为人们接受,普遍认为是目前最优秀的公钥方案之一。
5,平时使用的https中的ssl3.0和TSL1.0使用了RSA来加密密钥,还有就是数字证书、数字签名、数字签章、数字水印、数字信封等。如:银行的u盾、银行卡的刷卡机、淘宝的数字证书都使用了RSA进行加密。
⑵ 非对称加密之-RSA加密
对一个大整数进行因数分解,在高等数学中叫做费马大定理,至今没有被破解
RSA算法是最流行的公钥密码算法,使用长度可以变化的密钥。RSA是第一个既能用于数据加密也能用于数字签名的算法。
这是目前地球上最重要的加密算法
至此,所有计算完成。
将 n和e封装成公钥 , n和d封装成私钥 。
回顾上面的密钥生成步骤,一共出现六个数字:
这六个数字之中,公钥用到了两个(n和e),其余四个数字都是不公开的。其中最关键的是d,因为n和d组成了私钥,一旦d泄漏,就等于私钥泄漏。
那么, 有无可能在已知n和e的情况下,推导出d?
最终转换成->结论: 如果n可以被因数分解,d就可以算出,也就意味着私钥被破解。
第一步 :首先生成秘钥对
第二步 :公钥加密
第三步 :私钥解密
几个全局变量解说:
关于加密填充方式:之前以为上面这些操作就能实现rsa加解密,以为万事大吉了,呵呵,这事还没完,悲剧还是发生了, android这边加密过的数据,服务器端死活解密不了, ,这造成了在android机上加密后无法在服务器上解密的原因,所以在实现的时候这个一定要注意
实现分段加密:搞定了填充方式之后又自信的认为万事大吉了,可是意外还是发生了,RSA非对称加密内容长度有限制,1024位key的最多只能加密127位数据,否则就会报错(javax.crypto.IllegalBlockSizeException: Data must not be longer than 117 bytes) ,RSA 是常用的非对称加密算法。最近使用时却出现了“不正确的长度”的异常,研究发现是由于待加密的数据超长所致。RSA 算法规定:待加密的字节数不能超过密钥的长度值除以 8 再减去 11(即:KeySize / 8 - 11),而加密后得到密文的字节数,正好是密钥的长度值除以 8(即:KeySize / 8)。
爱丽丝选择了61和53。(实际应用中,这两个质数越大,就越难破解。)
爱丽丝就把61和53相乘
n的长度就是密钥长度。3233写成二进制是110010100001,一共有12位,所以这个密钥就是12位。实际应用中,RSA密钥一般是1024位,重要场合则为2048位
爱丽丝算出φ(3233)等于60×52,即3120。
爱丽丝就在1到3120之间,随机选择了17。(实际应用中,常常选择65537。)
所谓 "模反元素" 就是指有一个整数d,可以使得ed被φ(n)除的余数为1。
这个式子等价于
于是,找到模反元素d,实质上就是对下面这个二元一次方程求解。
已知 e=17, φ(n)=3120,
至此所有计算完成
在爱丽丝的例子中,n=3233,e=17,d=2753,所以公钥就是 (3233,17),私钥就是(3233, 2753)。
实际应用中,公钥和私钥的数据都采用 ASN.1 格式表达
回顾上面的密钥生成步骤,一共出现六个数字:
这六个数字之中,公钥用到了两个(n和e),其余四个数字都是不公开的。其中最关键的是d,因为n和d组成了私钥,一旦d泄漏,就等于私钥泄漏。
那么,有无可能在已知n和e的情况下,推导出d?
结论:如果n可以被因数分解,d就可以算出,也就意味着私钥被破解。
可是,大整数的因数分解,是一件非常困难的事情。目前,除了暴力破解,还没有发现别的有效方法。维基网络这样写道
举例来说,你可以对3233进行因数分解(61×53),但是你没法对下面这个整数进行因数分解。
它等于这样两个质数的乘积
事实上,RSA加密的方式原理是一个高等数学中没有被解决的难题,所有没有可靠的RSA的破解方式
⑶ 请较为详细地描述rsa加密算法的全过程
RSA算法非常简单,概述如下:
找两素数p和q
取n=p*q
取t=(p-1)*(q-1)
取任何一个数e,要求满足e<t并且e与t互素(就是最大公因数为1)
取d*e%t==1
这样最终得到三个数: n d e
设消息为数M (M <n)
设c=(M**d)%n就得到了加密后的消息c
设m=(c**e)%n则 m == M,从而完成对c的解密。
注:**表示次方,上面两式中的d和e可以互换。
在对称加密中:
n d两个数构成公钥,可以告诉别人;
n e两个数构成私钥,e自己保留,不让任何人知道。
给别人发送的信息使用e加密,只要别人能用d解开就证明信息是由你发送的,构成了签名机制。
别人给你发送信息时使用d加密,这样只有拥有e的你能够对其解密。
rsa的安全性在于对于一个大数n,没有有效的方法能够将其分解
从而在已知n d的情况下无法获得e;同样在已知n e的情况下无法
求得d。
rsa简洁幽雅,但计算速度比较慢,通常加密中并不是直接使用rsa 来对所有的信息进行加密,
最常见的情况是随机产生一个对称加密的密钥,然后使用对称加密算法对信息加密,之后用
RSA对刚才的加密密钥进行加密。
最后需要说明的是,当前小于1024位的N已经被证明是不安全的
自己使用中不要使用小于1024位的RSA,最好使用2048位的。
⑷ java rsa私钥加密
java rsa私钥加密是什么?让我们一起来了解一下吧!
java rsa私钥加密是一种加密算法。私钥加密算法是用私钥来进行加密与解密信息。私钥加密也被称作对称加密,原因是加密与解密使用的秘钥是同一个。
RSA加密需要注意的事项如下:
1. 首先产生公钥与私钥
2. 设计加密与解密的算法
3. 私钥加密的数据信息只能由公钥可以解密
4. 公钥加密的数据信息只能由私钥可以解密
实战演练,具体步骤如下: public class RsaCryptTools { private static final String CHARSET = "utf-8"; private static final Base64.Decoder decoder64 = Base64.getDecoder(); private static final Base64.Encoder encoder64 = Base64.getEncoder(); /** * 生成公私钥 * @param keySize * @return * @throws NoSuchAlgorithmException */ public static SecretKey generateSecretKey(int keySize) throws NoSuchAlgorithmException { //生成密钥对 KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA"); keyGen.initialize(keySize, new SecureRandom()); KeyPair pair = keyGen.generateKeyPair(); PrivateKey privateKey = pair.getPrivate(); PublicKey publicKey = pair.getPublic(); //这里可以将密钥对保存到本地 return new SecretKey(encoder64.encodeToString(publicKey.getEncoded()), encoder64.encodeToString(privateKey.getEncoded())); } /** * 私钥加密 * @param data * @param privateInfoStr * @return * @throws IOException * @throws InvalidCipherTextException */ public static String encryptData(String data, String privateInfoStr) throws IOException, InvalidKeySpecException, NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException, BadPaddingException, IllegalBlockSizeException { Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); cipher.init(Cipher.ENCRYPT_MODE, getPrivateKey(privateInfoStr)); return encoder64.encodeToString(cipher.doFinal(data.getBytes(CHARSET))); } /** * 公钥解密 * @param data * @param publicInfoStr * @return */ public static String decryptData(String data, String publicInfoStr) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, UnsupportedEncodingException { byte[] encryptDataBytes=decoder64.decode(data.getBytes(CHARSET)); //解密 Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); cipher.init(Cipher.DECRYPT_MODE, getPublicKey(publicInfoStr)); return new String(cipher.doFinal(encryptDataBytes), CHARSET); } private static PublicKey getPublicKey(String base64PublicKey) throws NoSuchAlgorithmException, InvalidKeySpecException { X509EncodedKeySpec keySpec = new X509EncodedKeySpec(Base64.getDecoder().decode(base64PublicKey.getBytes())); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); return keyFactory.generatePublic(keySpec); } private static PrivateKey getPrivateKey(String base64PrivateKey) throws NoSuchAlgorithmException, InvalidKeySpecException { PrivateKey privateKey = null; PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(Base64.getDecoder().decode(base64PrivateKey.getBytes())); KeyFactory keyFactory = null; keyFactory = KeyFactory.getInstance("RSA"); privateKey = keyFactory.generatePrivate(keySpec); return privateKey; } /** * 密钥实体 * @author hank * @since 2020/2/28 0028 下午 16:27 */ public static class SecretKey { /** * 公钥 */ private String publicKey; /** * 私钥 */ private String privateKey; public SecretKey(String publicKey, String privateKey) { this.publicKey = publicKey; this.privateKey = privateKey; } public String getPublicKey() { return publicKey; } public void setPublicKey(String publicKey) { this.publicKey = publicKey; } public String getPrivateKey() { return privateKey; } public void setPrivateKey(String privateKey) { this.privateKey = privateKey; } @Override public String toString() { return "SecretKey{" + "publicKey='" + publicKey + '\'' + ", privateKey='" + privateKey + '\'' + '}'; } } private static void writeToFile(String path, byte[] key) throws IOException { File f = new File(path); f.getParentFile().mkdirs(); try(FileOutputStream fos = new FileOutputStream(f)) { fos.write(key); fos.flush(); } } public static void main(String[] args) throws NoSuchAlgorithmException, NoSuchPaddingException, IOException, BadPaddingException, IllegalBlockSizeException, InvalidKeyException, InvalidKeySpecException { SecretKey secretKey = generateSecretKey(2048); System.out.println(secretKey); String enStr = encryptData("你好测试测试", secretKey.getPrivateKey()); System.out.println(enStr); String deStr = decryptData(enStr, secretKey.getPublicKey()); System.out.println(deStr); enStr = encryptData("你好测试测试hello", secretKey.getPrivateKey()); System.out.println(enStr); deStr = decryptData(enStr, secretKey.getPublicKey()); System.out.println(deStr); } }
⑸ 如何使用16进制编码的RSA公钥进行RSA加密
我们来回顾一下RSA的加密算法。我们从公钥加密算法和签名算法的定义出发,用比较规范的语言来描述这一算法。RSA公钥加密体制包含如下3个算法:KeyGen(密钥生成算法),Encrypt(加密算法)以及Decrypt(解密算法)。(PK,SK)\leftarrowKeyGen(\lambda)。密钥生成算法以安全常数\lambda作为输入,输出一个公钥PK,和一个私钥SK。安全常数用于确定这个加密算法的安全性有多高,一般以加密算法使用的质数p的大小有关。\lambda越大,质数p一般越大,保证体制有更高的安全性。在RSA中,密钥生成算法如下:算法首先随机产生两个不同大质数p和q,计算N=pq。随后,算法计算欧拉函数\varphi(N)=(p-1)(q-1)。接下来,算法随机选择一个小于\varphi(N)的整数e,并计算e关于\varphi(N)的模反元素d。最后,公钥为PK=(N,e),私钥为SK=(N,d)。CT\leftarrowEncrypt(PK,M)。加密算法以公钥PK和待加密的消息M作为输入,输出密文CT。在RSA中,加密算法如下:算法直接输出密文为CT=M^e\mod\varphi(N)M\leftarrowDecrypt(SK,CT)。解密算法以私钥SK和密文CT作为输入,输出消息M。在RSA中,解密算法如下:算法直接输出明文为M=CT^d\mod\varphi(N)。由于e和d在\varphi(N)下互逆,因此我们有:CT^d=M^{ed}=M\mod\varphi(N)所以,从算法描述中我们也可以看出:公钥用于对数据进行加密,私钥用于对数据进行解密。当然了,这个也可以很直观的理解:公钥就是公开的密钥,其公开了大家才能用它来加密数据。私钥是私有的密钥,谁有这个密钥才能够解密密文。否则大家都能看到私钥,就都能解密,那不就乱套了。=================分割线=================我们再来回顾一下RSA签名体制。签名体制同样包含3个算法:KeyGen(密钥生成算法),Sign(签名算法),Verify(验证算法)。(PK,SK)\leftarrowKeyGen(\lambda)。密钥生成算法同样以安全常数\lambda作为输入,输出一个公钥PK和一个私钥SK。在RSA签名中,密钥生成算法与加密算法完全相同。\sigma\leftarrowSign(SK,M)。签名算法以私钥SK和待签名的消息M作为输入,输出签名\sigma。在RSA签名中,签名算法直接输出签名为\sigma=M^d\mod\varphi(N)。注意,签名算法和RSA加密体制中的解密算法非常像。b\leftarrowVerify(PK,\sigma,M)。验证算法以公钥PK,签名\sigma以及消息M作为输入,输出一个比特值b。b=1意味着验证通过。b=0意味着验证不通过。在RSA签名中,验证算法首先计算M'=\sigma^e\mod\varphi(N),随后对比M'与M,如果相等,则输出b=1,否则输出b=0。注意:验证算法和RSA加密体制中的加密算法非常像。所以,在签名算法中,私钥用于对数据进行签名,公钥用于对签名进行验证。这也可以直观地进行理解:对一个文件签名,当然要用私钥,因为我们希望只有自己才能完成签字。验证过程当然希望所有人都能够执行,大家看到签名都能通过验证证明确实是我自己签的。=================分割线=================那么,为什么题主问这么一个问题呢?我们可以看到,RSA的加密/验证,解密/签字过程太像了。同时,RSA体制本身就是对称的:如果我们反过来把e看成私钥,d看成公钥,这个体制也能很好的执行。我想正是由于这个原因,题主在学习RSA体制的时候才会出现这种混乱。那么解决方法是什么呢?建议题主可以学习一下其他的公钥加密体制以及签名体制。其他的体制是没有这种对称性质的。举例来说,公钥加密体制的话可以看一看ElGamal加密,以及更安全的Cramer-Shoup加密。签名体制的话可以进一步看看ElGamal签名,甚至是BLS签名,这些体制可能能够帮助题主更好的弄清加密和签名之间的区别和潜在的联系。至于题主问的加密和签名是怎么结合的。这种体制叫做签密方案(SignCrypt),RSA中,这种签密方案看起来特别特别像,很容易引起混乱。在此我不太想详细介绍RSA中的加密与签字结合的方案。我想提醒题主的是,加密与签字结合时,两套公私钥是不同的。
⑹ RSA加解密原理
RSA是目前使用最为广泛的公钥密码算法,公钥加密也称为非对称加密,与对称加密的最大区别在于加密与解密使用不同的密钥。
在RSA中,明文、密文和密钥都是数字,假设公钥用二元组(E,N)来表示,私钥用(D,N)来表示,其中E、D、N都是数字,那么加解密过程可表示如下:
可见,在RSA中,不论加密还是解密,都可归结为求x的y次幂对m取余问题。
生成RSA密钥可分成以下4步:
首先准备两个很大的质数p和q,那么N = p * q。
L = lcm(p-1, q-1)
由于存在恒等式gcd(a,b) * lcm(a,b) = a * b,求lcm可转换为求gcd,而求gcd可通过欧几里德算法在对数时间内算出。
E是一个比1大、比L小的数,且满足E与L互质,即有:gcd(E,L)=1, 1 < E < L。gcd(E,L)=1是为了保证后面要求的数字D一定存在。
可不断地生成[2,L-1]之间的随机数作为E的候选数,检查是否满足条件,直到找出符合要求的E为止。
至此,E和N都已求出,那么公钥(E,N)也就得到了。
数D是由数E计算得到的,D、E和L之间满足关系:E * D mod L = 1, 1 < D < L。
只要D满足上述条件,那么通过E与N加密的内容,就可通过D和N进行解密。
求D也可采用类似求E的方法,不断产生随机数去试,直到找出满足条件的D为止,这样私钥(D,N)也准备好了。
为方面说明,这里用较小的数计算。先准备两个质数,例如,p=17, q=19,那么N=17*19=323,L=lcd(16,18)=144。
满足gcd(E,L)=1的数很多,例如5,7,11,13,25等,这里取E=5。
满足E*D mod L = 1的数也很多,这里取D=29。
到这里,公私钥都有了,公钥为(5,323),私钥为(29,323),公钥可任意公开,私钥则保密。
明文必须是小于N的数,因为加密运算中要求mod N。假设明文是123,用公钥(5,323)对其加密:
再用私钥(29,323)对密文225进行解密:
解出的明文与原始明文一致。
⑺ RSA加密、解密、签名、验签的原理及方法
RSA加密是一种非对称加密。可以在不直接传递密钥的情况下,完成解密。这能够确保信息的安全性,避免了直接传递密钥所造成的被破解的风险。是由一对密钥来进行加解密的过程,分别称为公钥和私钥。两者之间有数学相关,该加密算法的原理就是对一极大整数做因数分解的困难性来保证安全性。通常个人保存私钥,公钥是公开的(可能同时多人持有)。
加密和签名都是为了安全性考虑,但略有不同。常有人问加密和签名是用私钥还是公钥?其实都是对加密和签名的作用有所混淆。简单的说,加密是为了防止信息被泄露,而签名是为了防止信息被篡改。这里举2个例子说明。
RSA的加密过程如下:
RSA签名的过程如下:
总结:公钥加密、私钥解密、私钥签名、公钥验签。
RSA加密对明文的长度有所限制,规定需加密的明文最大长度=密钥长度-11(单位是字节,即byte),所以在加密和解密的过程中需要分块进行。而密钥默认是1024位,即1024位/8位-11=128-11=117字节。所以默认加密前的明文最大长度117字节,解密密文最大长度为128字。那么为啥两者相差11字节呢?是因为RSA加密使用到了填充模式(padding),即内容不足117字节时会自动填满,用到填充模式自然会占用一定的字节,而且这部分字节也是参与加密的。
⑻ linux生成的rsa秘钥在哪
方法一, 有的时候经常需要登录ssh,每次都需要输入密码,会比较繁琐。所以设置了一下使用RSA公钥认证的方式登录Linux。 首先需要在服务器端设置/etc/ssh/sshd_config # vim /etc/ssh/sshd_config 修改如下两行为yes。其实大多数情况下不用修改,默认就是yes。 RSAAuthentication yes PubkeyAuthentication yes (1) 如果客户机和服务器都是Linux机器,那么我们使用下面的方法:(后面第2节会提到怎么在Windows下使用Putty生成密钥对) 我们需要在客户端生成RSA密钥对。使用ssh-keygen命令: # ssh-keygen -t rsa 参数t的意思是type,后面跟着加密类型,这里我们是rsa。 然后会提示你输入密钥保存完成文件名,这里我们需要使用默认的id_rsa,之后才能正常才能登录。如果你生成的密钥作为其他用处,那么可以命名为其他名称: Generating public/private rsa key pair. Enter file in which to save the key (/home/cake/.ssh/id_rsa): 之后会提示你输入一个passphrase,我们这里可以留空,这样我们登录的时候就不许输入密码。 Enter passphrase (empty for no passphrase): Enter same passphrase again: 然后会提示你密钥生成成功。这是你的私钥保存为~/.ssh/id_rsa,你的公钥是~/.ssh/id_rsa.pub 我们现在需要做的是,把id_rsa.pub的内容,添加的服务器端的~/.ssh/autherized_keys文件最后。 你可以把这个文件上传到服务器端,然后使用命令: # cat id_rsa.pub >> ~/.ssh/autherized_keys 到这里就完成了。 (2) 在Windows下使用Putty生成密钥对: Putty的安装目录下有个puttygen.exe程序,我们运行这个程序。 之后点击Generate,开始生成密钥对。我们需要根据提示,在指定方框内随机滑动鼠标。这是为了根据鼠标轨迹,产生一些随机数据。 之后生成结束,我们点击Save Private Key将私钥存放在某个目录中。然后赋值最上面文本框中的全部内容,粘贴到Linux服务器端的autherized_key的最后。 我们现在可以关闭这个小程序。 现在打开Putty,在左边的选项中,选择Conneciton–SSH–Auth,在Private key file for authentication中,选择刚才保存的私钥路径就可以了。 到此位置,Putty也可以不用密码登录了。 方法二 使用Linux主机生成的密匙 1、生成密匙 [root@ .ssh]#ssh-keygen -t rsa Generating public/private rsa key pair. Enter file in which to save the key (/root/.ssh/id_rsa): Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /root/.ssh/id_rsa. Your public key has been saved in /root/.ssh/id_rsa.pub. The key fingerprint is: e4:9a:47:a7:b4:8a:0b:98:07:b8:70:de:6b:16:2c:0croot@ 2、将 /root/.ssh/id_rsa.pub改名为/root/.ssh/authorized_keys [root@ .ssh]#mv /root/.ssh/id_rsa.pub /root/.ssh/authorized_keys 3、将私钥id_rsa拷贝到远程客户端 1)、如果远程客户端是linux,拷贝到远程客户端/root/.ssh/即可 2)、putty作为远程客户端在 putty不能识别直接从服务器拷贝来的私钥,需要使用puttygen.exe进行格式转换 (1)、打开puttygen.exe --> Conversions --> Import Key (2)、选择拷贝过来的私钥文件id_rsa (3)、Save private key->id_rsa.ppk(保存私钥) 4、打开putty.exe 1)、Session --> Host Name (填写服务器地址或者域名) 2)、Connection --> SSH --> Auth (点Browse选择刚生成的id_rsa.ppk) 3)、open 成功打开后出现如下提示: login as: root Authenticating with public key "imported-openssh-key" ---------------------------------------------------------------------------------- 当然你有可能会遇到这个错误 [因为我遇到了,呵呵]: Permissions 0755 for '你配置的公钥文件路径' are too open. 这个是因为这几个文件权限设置的有点问题 执行命令: chmod 600 你的文件
⑼ RSA 加密算法(原理篇)
前几天看到一句话,“我们中的很多人把一生中最灿烂的笑容大部分都献给了手机和电脑屏幕”。心中一惊,这说明了什么?手机和电脑已经成为了我们生活中的一部分,所以才会有最懂你的不是你,也不是你男朋友,而是大数据。
如此重要的个人数据,怎样才能保证其在互联网上的安全传输呢?当然要靠各种加密算法。说起加密算法,大家都知道有哈希、对称加密和非对称加密了。哈希是一个散列函数,具有不可逆操作;对称加密即加密和解密使用同一个密钥,而非对称加密加密和解密自然就是两个密钥了。稍微深入一些的,还要说出非对称加密算法有DES、3DES、RC4等,非对称加密算法自然就是RSA了。那么当我们聊起RSA时,我们又在聊些什么呢?今天笔者和大家一起探讨一下,有不足的地方,还望各位朋友多多提意见,共同进步。
RSA简介:1976年由麻省理工学院三位数学家共同提出的,为了纪念这一里程碑式的成就,就用他们三个人的名字首字母作为算法的命名。即 罗纳德·李维斯特 (Ron Rivest)、 阿迪·萨莫尔 (Adi Shamir)和 伦纳德·阿德曼 (Leonard Adleman)。
公钥:用于加密,验签。
私钥:解密,加签。
通常知道了公钥和私钥的用途以后,即可满足基本的聊天需求了。但是我们今天的主要任务是来探究一下RSA加解密的原理。
说起加密算法的原理部分,肯定与数学知识脱不了关系。
我们先来回忆几个数学知识:
φn = φ(A*B)=φ(A)*φ(B)=(A-1)*(B-1)。
这个公式主要是用来计算给定一个任意的正整数n,在小于等于n的正整数中,有多少个与n构成互质的关系。
其中n=A*B,A与B互为质数,但A与B本身并不要求为质数,可以继续展开,直至都为质数。
在最终分解完成后,即 φ(N) = φ(p1)*φ(p2)*φ(p3)... 之后,p1,p2,p3都是质数。又用到了欧拉函数的另一个特点,即当p是质数的时候,φp = p - 1。所以有了上面给出的欧拉定理公式。
举例看一下:
计算15的欧拉函数,因为15比较小,我们可以直接看一下,小于15的正整数有 1、2、3、4、5、6、7、8、9、10、11、12、13、14。和15互质的数有1、2、4、7、8、11、13、14一共四个。
对照我们刚才的欧拉定理: 。
其他感兴趣的,大家可以自己验证。
之所以要在这里介绍欧拉函数,我们在计算公钥和私钥时候,会用到。
如果两个正整数m 和 n 互质,那么m 的 φn 次方减1,可以被n整除。
其中 .
其中当n为质数时,那么 上面看到的公式就变成了
mod n 1.
这个公式也就是着名的 费马小定理 了。
如果两个正整数e和x互为质数,那么一定存在一个整数d,不止一个,使得 e*d - 1 可以被x整除,即 e * d mode x 1。则称 d 是 e 相对于 x的模反元素。
了解了上面所讲的欧拉函数、欧拉定理和模反元素后,就要来一些化学反应了,请看图:
上面这幅图的公式变化有没有没看明白的,没看明白的咱们评论区见哈。
最终我们得到了最重要的第5个公式的变形,即红色箭头后面的:
mod n m。
其中有几个关系,需要搞明白,m 与 n 互为质数,φn = x,d 是e相对于x的模反元素。
有没有看到一些加解密的雏形。
从 m 到 m。 这中间涵盖了从加密到解密的整个过程,但是缺少了我们想要的密文整个过程。
OK,下面引入本文的第四个数学公式:
我们来看一下整个交换流程:
1、客户端有一个数字13,服务端有一个数字15;
2、客户端通过计算 3的13次方 对 17 取余,得到数字12; 将12发送给服务端;同时服务端通过计算3的15次方,对17取余,得到数字6,将6发送给客户端。至此,整个交换过程完成。
3、服务端收到数字12以后,继续计算,12的15次方 对 17取余,得到 数字10。
4、客户端收到数字 6以后,继续计算,6的13次方 对 17 取余,得到数字 10。
有没有发现双方,最终得到了相同的内容10。但是这个数字10从来没有在网络过程中出现过。
好,讲到这里,可能有些人已经恍然大悟,这就是加密过程了,但是也有人会产生疑问,为什么要取数字3 和 17 呢,这里还牵涉到另一个数学知识,原根的问题。即3是17的原根。看图
有没有发现规律,3的1~16次方,对17取余,得到的整数是从1~16。这时我们称3为17的原根。也就是说上面的计算过程中有一组原根的关系。这是最早的迪菲赫尔曼秘钥交换算法。
解决了为什么取3和17的问题后,下面继续来看最终的RSA是如何产生的:
还记得我们上面提到的欧拉定理吗,其中 m 与 n 互为质数,n为质数,d 是 e 相对于 φn的模反元素。
当迪菲赫尔曼密钥交换算法碰上欧拉定理会产生什么呢?
我们得到下面的推论:
好,到这里我们是不是已经看到了整个的加密和解密过程了。
其中 m 是明文;c 是密文; n 和 e 为公钥;d 和 n 为私钥 。
其中几组数字的关系一定要明确:
1、d是e 相对于 φn 的模反元素,φn = n-1,即 e * d mod n = 1.
2、m 小于 n,上面在讲迪菲赫尔曼密钥交换算法时,提到原根的问题,在RSA加密算法中,对m和n并没有原根条件的约束。只要满足m与n互为质数,n为质数,且m < n就可以了。
OK,上面就是RSA加密算法的原理了,经过上面几个数学公式的狂轰乱炸,是不是有点迷乱了,给大家一些时间理一下,后面会和大家一起来验证RSA算法以及RSA为什么安全。