1.RSA
RSA加密算法,它是1977年由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)共同提出的一种加密算法,RSA就是他们三人姓氏开头字母拼在一起组成的。
RSA算法是一种非对称加密算法,这一算法主要依靠分解大素数的复杂性来实现其安全性,由于大素数之积难被分解,因此该密码就难被破解。
1.1 RSA 原理
RSA基于一个十分简单的数论事实:将两个大素数相乘十分容易,但想要对其乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥,即公钥,而两个大素数组合成私钥。公钥是可发布的供任何人使用,私钥则为自己所有,供解密之用。
1.2 加密与解密
非对称加密加密,最大的特点就是加密与解密使用的不是同一个秘钥。一般来说,秘钥在分发过程中,会有丢失的风险,这也就意味着别人可以获取秘钥,密文,因而可以解密得到明文。而非对称加密,公钥对所有人公开,使用公钥对明文加密得到密文。要想对密文进行解密,必须要使用私钥进行解密。私钥不需要发送给别人,只有解密者拥有。这样即使别人获取了密文,也没有私钥可以解密。降低了数据泄露的风险。
1.3 签名与验签
公钥私钥还有另外一种用途:签名。即用秘钥拥有者用私钥对数据进行签名,然后把数据发送出去,这时候所有人都可以获取到数据,但是数据是否被篡改了呢?拥有公钥的用户可以对私钥签名后的数据进行验证,这一步称为验签。如果签名验证通过,即可以认为数据是完整的。
1.4 公钥长度
我们经常会听到RSA-512, RSA-1024,这里的512,1024是什么呢?这里的1024指的是公钥的比特长度,即RSA-1024所生成的公钥长度为1024bit,即1024/8=128bytes。
秘钥的长度越长,安全性越好,加密与解密的所需要的时间也就越长。密钥长度增加一倍,公钥操作所需时间增加约 4 倍,私钥操作所需时间增加约 8 倍,公私钥生成时间约增长 16 倍。
RSA 算法密钥长度的选择是安全性和程序性能平衡的结果。不过也不要选择特别短的,首先JAVA要求不得低于512。其次,根据相关显示,目前被破解的最长RSA密钥是768个二进制位。也就是说,长度超过768位的密钥,还未被破解,至少目前尚未有人公开宣布。(ps:一些非官方报道称,1024位的已经被解密)
1.5 加密明文长度
RSA算法一次能加密的明文长度与公钥长度相同,如RSA-1024算法一次可实际加密的最大明文长度为1024bits,生成的密文长度与公钥长度相同。但是如果明文长度小于1024bits怎么办?那就进行数据补齐,也就是padding。用padding,那么padding就会占据一定的位数,根据不同的padding标准,所占的位数也不同。常见的padding标准有NoPPadding、PKCS1Padding等。NoPPadding即意味着不占据长度,PKCS1Padding占据11个字节。一般情况下,我们会使用PKCS1Padding,这样可以让同样的明文使用相同的秘钥加密,也可以得到不同的密文。
由于PKCS1Padding占据11个字节,那么RSA-1024算法一次能加密的明文的实际长度就是1024/8-11=117字节。这也就是我们为什么会说RSA-1024一次只能加密117个字节的内容,超过117个字节的内容需要多次加密。然后将加密内容连接起来。
这样做得话解密怎么做呢?解密也要将拼接的字符串再拆开。由于一次生成的密文长度与公钥长度相同,因此可以轻而易举的将数据分段解密。
2. JAVA应用
由于为了方便,将密钥,密文等都用base64编码成字符串,这样方便copy等。
import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import java.io.ByteArrayOutputStream;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
public class RSAUtil extends AbstractCrypto {
private static final String RSA_ALGORITHM = "RSA";
private static final int RSA_2048 = 2048;
public void generateSecret() throws Exception {
KeyPairGenerator keyP

本文深入介绍了RSA加密算法的原理及应用,包括加密与解密过程、签名与验签功能,并探讨了公钥长度与加密明文长度的影响。同时提供了JAVA与Python的实现案例。
最低0.47元/天 解锁文章

被折叠的 条评论
为什么被折叠?



