RSA的三个重要大数分别为公钥指数e、私钥指数d和模值n。
RSA密钥对是由(公钥指数e+模值n)、(私钥指数d+模值n)组成。
RSA密钥的长度是指模值的bit数,通常的长度有768,1024,2048、3072、4096...
常用的公钥指数为1或65537。
RSA算法对明文长度存在要求。若超过最大长度,将抛出异常。
密文长度固定,等于模长。
如果不padding,则明文最大长度为模值长度。
如果存在padding,那么RSA_PKCS1_PADDING模式下, 明文最大长度为模值长度-11字节。该模式为默认模式。
如果存在padding,那么RSA_PKCS1_OAEP_PADDING模式下, 明文最大长度为模值长度-41字节。
虽然明文长度受Padding模式影响,但每次加密的block长度都为模值长度。
对于NO_PADDING的情况,若密文长度小于模值长度,则在明文前端加0x00,解密时并不把0x00自动删除。
JAVA
RSA工具类
package com.breakloop.common;
import javax.crypto.Cipher;
import java.math.BigInteger;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.*;
public class RSAUtil {
public static final int KEY_BIT_LENGTH_4096=4096;
public static final int KEY_BIT_LENGTH_3072=3072;
public static final int KEY_BIT_LENGTH_2048=2048;
public static final int KEY_BIT_LENGTH_1024=1024;
public static final int KEY_BIT_LENGTH_768=768;
private static final String ALGO_CIPHER="RSA/ECB/NoPadding";
private static final String SIGN_ALGORITHMS="SHA1WithRSA";
public static KeyPair generateRSAKeyPair(int keyBitLength){
KeyPair keyPair=null;
try {
KeyPairGenerator keyPairGenerator=KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(keyBitLength,new SecureRandom());
keyPair=keyPairGenerator.generateKeyPair();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return keyPair;
}
public static byte[] getRSAPubKey(KeyPair keyPair){
RSAPublicKey publicKey=(RSAPublicKey)keyPair.getPublic();
return publicKey.getEncoded();
}
public static byte[] getRSAPriKey(KeyPair keyPair){
RSAPrivateKey privateKey=(RSAPrivateKey)keyPair.getPrivate();
return privateKey.getEncoded();
}
public static PublicKey getPublicKey(byte[] encoded){
KeyFactory keyFactory = null;
PublicKey publicKey=null;
try {
keyFactory = KeyFactory.getInstance("RSA");
X509EncodedKeySpec bobPubKeySpec = new X509EncodedKeySpec(
encoded);
publicKey = keyFactory.generatePublic(bobPubKeySpec);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}catch (InvalidKeySpecException e) {
e.printStackTrace();
}
return publicKey;
}
public static PrivateKey getPrivateKey(byte[] encoded){
KeyFactory keyFactory;
PrivateKey privateKey=null;
try {
keyFactory = KeyFactory.getInstance("RSA");
PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(
encoded);
privateKey = keyFactory.generatePrivate(priPKCS8);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeySpecException e) {
e.printStackTrace();
}
return privateKey;
}
public static PublicKey getPublicKey(byte[] modulus, byte[] exponent){
BigInteger bigIntegerModulus=new BigInteger(modulus);
BigInteger bigIntegerExponent=new BigInteger(exponent);
RSAPublicKeySpec keySpec=new RSAPublicKeySpec(bigIntegerModulus,bigIntegerExponent);
KeyFactory keyFactory= null;
PublicKey publicKey= null;
try {
keyFactory = KeyFactory.getInstance("RSA");
publicKey = keyFactory.generatePublic(keySpec);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeySpecException e) {
e.printStackTrace();
}
return publicKey;
}
public static PrivateKey getPrivateKey(byte[] modulus, byte[] exponent){
BigInteger bigIntegerModulus=new BigInteger(modulus);
BigInteger bigIntegerExponent=new BigInteger(exponent);
RSAPrivateKeySpec keySpec=new RSAPrivateKeySpec(bigIntegerModulus,bigIntegerExponent);
KeyFactory keyFactory= null;
PrivateKey privateKey= null;
try {
keyFactory = KeyFactory.getInstance("RSA");
privateKey = keyFactory.generatePrivate(keySpec);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeySpecException e) {
e.printStackTrace();
}
return privateKey;
}
public static byte[] encrypt(PublicKey publicKey, byte[] data) {
if (publicKey != null) {
try {
Cipher cipher = Cipher.getInstance(ALGO_CIPHER);
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
return cipher.doFinal(data);
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
public static byte[] decrypt(PrivateKey privateKey, byte[] raw) {
if (privateKey != null) {
try {
Cipher cipher = Cipher.getInstance(ALGO_CIPHER);
cipher.init(Cipher.DECRYPT_MODE, privateKey);
return cipher.doFinal(raw);
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
public static byte[] cipher(Key key,byte[] data,boolean isEncrypt){
try {
Cipher cipher = Cipher.getInstance(ALGO_CIPHER);
cipher.init(isEncrypt?Cipher.ENCRYPT_MODE:Cipher.DECRYPT_MODE, key);
return cipher.doFinal(data);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static boolean verify(byte[] content, byte[] sign, byte[] pubModulus, byte[] pubExponent) {
try {
PublicKey pubKey = getPublicKey(pubModulus,pubExponent);
Signature signature = Signature.getInstance(SIGN_ALGORITHMS);
signature.initVerify(pubKey);
signature.update( content );
return signature.verify(sign);
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
public static byte[] sign(byte[] content, byte[] priModulus, byte[] priExponent) {
try {
PrivateKey priKey = getPrivateKey(priModulus,priExponent);
Signature signature = Signature.getInstance(SIGN_ALGORITHMS);
signature.initSign(priKey);
signature.update( content);
byte[] signed = signature.sign();
return signed;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
参考博文:
http://blog.csdn.net/lvxiangan/article/details/45487943
http://blog.csdn.net/luoluo_onion/article/details/78354799
https://www.cnblogs.com/lzl-sml/p/3501447.html