关于Java中RSA加签解签,私钥加密公钥解密和公钥加密私钥解密代码详解
关于Java中RSA加签解签,私钥加密公钥解密和公钥加密私钥解密,一般为了安全采用的是
- 私钥加签,公钥验签
- 本地私钥加密,远程公钥解密(公钥可以用Base64转换后公开)
- 远程公钥加密,本地私钥解密
import org.apache.commons.codec.binary.Base64;
import javax.crypto.Cipher;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Arrays;
/**
* <p>
* 封装同RSA非对称加密算法有关的方法,可用于数字签名,RSA加密解密
* </p>
*
* @Copyright:WDSsoft
*/
public class RSAUtil {
/**
* 使用私钥加密数据
* 用一个已打包成byte[]形式的私钥加密数据,即数字签名
*
* @param keyInByte 打包成byte[]的私钥
* @param source 要签名的数据,一般应是数字摘要
* @return 签名 byte[]
*/
public static byte[] sign(byte[] keyInByte, byte[] source) {
try {
PKCS8EncodedKeySpec priv_spec = new PKCS8EncodedKeySpec(keyInByte);
KeyFactory mykeyFactory = KeyFactory.getInstance("RSA");
PrivateKey privKey = mykeyFactory.generatePrivate(priv_spec);
Signature sig = Signature.getInstance("SHA1withRSA");
sig.initSign(privKey);
sig.update(source);
return sig.sign();
} catch (Exception e) {
return null;
}
}
/**
* 验证数字签名
*
* @param keyInByte 打包成byte[]形式的公钥
* @param source 原文的数字摘要
* @param sign 签名(对原文的数字摘要的签名)
* @return 是否证实 boolean
*/
public static boolean verify(byte[] keyInByte, byte[] source, byte[] sign) {
try {
KeyFactory mykeyFactory = KeyFactory.getInstance("RSA");
Signature sig = Signature.getInstance("SHA1withRSA");
X509EncodedKeySpec pub_spec = new X509EncodedKeySpec(keyInByte);
PublicKey pubKey = mykeyFactory.generatePublic(pub_spec);
sig.initVerify(pubKey);
sig.update(source);
return sig.verify(sign);
} catch (Exception e) {
return false;
}
}
/**
* 建立新的密钥对,返回打包的byte[]形式私钥和公钥
*
* @return 包含打包成byte[]形式的私钥和公钥的object[],其中,object[0]为私钥byte[],object[1]为公钥byte[]
*/
public static Object[] giveRSAKeyPairInByte() {
KeyPair keyPair = creatKey();
if (keyPair == null) {
return null;
}
Object[] re = new Object[2];
if (keyPair != null) {
PrivateKey pri = keyPair.getPrivate();
byte[] priBytes = pri.getEncoded();
PublicKey pub = keyPair.getPublic();
byte[] pubBytes = pub.getEncoded();
re[0] = priBytes;
re[1] = pubBytes;
return re;
}
return null;
}
/**
* 新建密钥对
*
* @return KeyPair对象
*/
public static KeyPair creatKey() {
KeyPair keyPair;
long mySeed;
mySeed = System.currentTimeMillis();
try {
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
SecureRandom random = SecureRandom.getInstance("SHA1PRNG", "SUN");
random.setSeed(mySeed);
keyGen.initialize(1024, random);
keyPair = keyGen.generateKeyPair();
} catch (Exception e1) {
return null;
}
return keyPair;
}
/**
* 使用RSA公钥加密数据
*
* @param pubKeyInByte 打包的byte[]形式公钥
* @param data 要加密的数据
* @return 加密数据
*/
public static byte[] encryptByPublicKey(byte[] pubKeyInByte, byte[] data) {
try {
KeyFactory mykeyFactory = KeyFactory.getInstance("RSA");
X509EncodedKeySpec pub_spec = new X509EncodedKeySpec(pubKeyInByte);
PublicKey pubKey = mykeyFactory.generatePublic(pub_spec);
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
return cipher.doFinal(data);
} catch (Exception e) {
return null;
}
}
/**
* 用RSA私钥解密
*
* @param privKeyInByte 私钥打包成byte[]形式
* @param data 要解密的数据
* @return 解密数据
*/
public static byte[] decryptByPrivateKey(byte[] privKeyInByte, byte[] data) {
try {
PKCS8EncodedKeySpec priv_spec = new PKCS8EncodedKeySpec(
privKeyInByte);
KeyFactory mykeyFactory = KeyFactory.getInstance("RSA");
PrivateKey privKey = mykeyFactory.generatePrivate(priv_spec);
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, privKey);
return cipher.doFinal(data);
} catch (Exception e) {
return null;
}
}
/**
* 使用RSA私钥加密数据
*
* @param privKeyInByte 打包的byte[]形式私钥
* @param data 要加密的数据
* @return 加密数据
*/
public static byte[] encryptByPrivateKey(byte[] privKeyInByte, byte[] data) {
try {
PKCS8EncodedKeySpec priv_spec = new PKCS8EncodedKeySpec(
privKeyInByte);
KeyFactory mykeyFactory = KeyFactory.getInstance("RSA");
PrivateKey privKey = mykeyFactory.generatePrivate(priv_spec);
Cipher cipher = Cipher.getInstance(mykeyFactory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, privKey);
return cipher.doFinal(data);
} catch (Exception e) {
return null;
}
}
/**
* 用RSA公钥解密
*
* @param pubKeyInByte 公钥打包成byte[]形式
* @param data 要解密的数据
* @return 解密数据
*/
public static byte[] decryptByPublicKey(byte[] pubKeyInByte, byte[] data) {
try {
KeyFactory mykeyFactory = KeyFactory.getInstance("RSA");
X509EncodedKeySpec pub_spec = new X509EncodedKeySpec(pubKeyInByte);
PublicKey pubKey = mykeyFactory.generatePublic(pub_spec);
Cipher cipher = Cipher.getInstance(mykeyFactory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, pubKey);
return cipher.doFinal(data);
} catch (Exception e) {
return null;
}
}
/**
* 计算字符串的SHA数字摘要,以byte[]形式返回
*/
public static byte[] MdigestSHA(String source) {
//byte[] nullreturn = { 0 };
try {
MessageDigest thisMD = MessageDigest.getInstance("SHA");
byte[] digest = thisMD.digest(source.getBytes("UTF-8"));
return digest;
} catch (Exception e) {
return null;
}
}
/**
* 测试
*/
public static void main(String[] args) {
try {
//私钥加密 公钥解密
//生成私钥-公钥对
Object[] v = giveRSAKeyPairInByte();
//获得摘要
byte[] source = MdigestSHA("假设这是要加密的客户数据");
//使用私钥对摘要进行加密 获得密文 即数字签名
byte[] sign = sign((byte[]) v[0], source);
//使用公钥对密文进行解密,解密后与摘要进行匹配
boolean yes = verify((byte[]) v[1], source, sign);
if (yes) {
System.out.println("匹配成功 合法的签名!");
}
//公钥加密私钥解密
//获得摘要
byte[] sourcepub_pri = ("13265986584||316494646546486498||01||public").getBytes("UTF-8");
//使用公钥对摘要进行加密 获得密文
byte[] signpub_pri = encryptByPublicKey((byte[]) v[1], sourcepub_pri);
//System.out.println("公钥加密密文:"+new String(Base64.encodeBase64(signpub_pri)));
//使用私钥对密文进行解密 返回解密后的数据
byte[] newSourcepub_pri = decryptByPrivateKey((byte[]) v[0], signpub_pri);
System.out.println("私钥解密:" + new String(newSourcepub_pri, "UTF-8"));
//对比源数据与解密后的数据
if (Arrays.equals(sourcepub_pri, newSourcepub_pri)) {
System.out.println("匹配成功 合法的私钥!");
}
//私钥加密公钥解密
//获得摘要
//byte[] source = MdigestSHA("假设这是要加密的客户数据");
byte[] source = ("13265986584||316494646546486498||01||private").getBytes("UTF-8");
//使用私钥对摘要进行加密 获得密文
byte[] encrypted = encryptByPrivateKey((byte[]) v[0], source);
//System.out.println("私钥加密密文:" + new String(Base64.encodeBase64(sign11)));
//使用公钥对密文进行解密 返回解密后的数据
byte[] decrypted = decryptByPublicKey((byte[]) v[1], encrypted);
System.out.println("公钥解密:" + new String(decrypted, "UTF-8"));
String PUBLICKEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCEGENnf3rdiO20isoLQqezw12FoWXII9FBw8nR1MWQ3X0CVzOsqY1hOmxD/YI9OB7WVIaVax5tj1l+wk6A0v85Z4OpGWqz4B5L3fCUlBwf/M6DXHlSN1OZttvQF3OeWvc6gvJHihR7pp18zc4KfCJx0Ry6IrGH/2SNOVE1AIgvRQIDAQAB";
String PRIVATEKEY = "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAIQYQ2d/et2I7bSKygtCp7PDXYWhZcgj0UHDydHUxZDdfQJXM6ypjWE6bEP9gj04HtZUhpVrHm2PWX7CToDS/zlng6kZarPgHkvd8JSUHB/8zoNceVI3U5m229AXc55a9zqC8keKFHumnXzNzgp8InHRHLoisYf/ZI05UTUAiC9FAgMBAAECgYAGNcHNds/G5G4QY8n1149cwx19b8YCL7Thu5ucUr1q/w6mcoUKY/oyjPWUCLH7wMyqVNTy51NJ4UhazjW0lrbK4ZbPDHFij9CiZ7QFASiQ/TQWaL+KSIWnE6/rK9IdouwFKxk+cvvLteZoAXP6mFcrsa7LzfkENiIMu7mjpTNHAQJBANXv9U5JWOAVhWHDQcEWKn7YKpAVRleXdeUeJrXcdkqBDI+P6suA9j+ahDREfu+x65wUsrJotPHUXgJG0TarJIUCQQCeEPLrv6Qvi5+nbn2Eifn/fjsmIdI0U2WZKDHWJEnLsRUuGDNYxVE/SPDNDedA2OHeFB6j0Kk/ECdsWnUq6zvBAkAgUGViFMwa1MVX1fFZo+p5TFdpef0s/9Cr8djxAULQ0BtAmAFkCa+oPcOYTXxK4jnvUmUHc69ZE7W7bEzvj/wtAkB50X4mClAzBFxK4XCC0QOG0HYtcStbgFpwqvWdn+Hvxc4Y9DW+WHPBXimXHvv2ki+gw8jJX2rQW1bGvwBFz30BAkASPkORJxVWv91StjI2f/HXDO5eG5/su/XIb3eajaLUSEdaQlcs3ywLrrJ0o3VAR0J9aq59cmp6em017AMnmbF7";
byte[] signPrivate = Base64.decodeBase64(PRIVATEKEY.getBytes());
byte[] signPublic = Base64.decodeBase64(PUBLICKEY.getBytes());
String publicPwd = "N/b4nYbbLFVq0yTAIOpNNydtNQUCQxQy0B7bD6kzxLMW2guYxXtWOC/9Z5dpWecx/y7d5CezUJ6cf/8++msiNie4DcKBaFDFPh5rPbjeEB+DRfhjcdR2BsVGXWLsq3dLYLgZObQXG6Tb9rXakuH34Y+6KIIwCjiODH2QAU+PSiM=";
String privatePwd = "MTMyNjU5ODY1ODR8fDMxNjQ5NDY0NjU0NjQ4NjQ5OHx8MDF8fHByaXZhdGU=";
//使用私钥对密文进行解密 返回解密后的数据
byte[] newSource = decryptByPrivateKey(signPrivate, Base64.decodeBase64(publicPwd.getBytes()));
System.out.println("私钥解密:" + new String(newSource, "UTF-8"));
} catch (Exception e) {
e.printStackTrace();
}
/*运行结果:
匹配成功 合法的签名!
私钥解密:13265986584||316494646546486498||01||public
匹配成功 合法的私钥!
公钥解密:13265986584||316494646546486498||01||private
私钥解密:13265986584||316494646546486498||01||3156464564
*/
}
}
版权声明:
作者:Joe.Ye
链接:https://www.appblog.cn/index.php/2023/02/25/detailed-explanation-of-java-rsa-signature-and-unsigning-private-key-encryption-public-key-decryption-and-public-key-encryption-private-key-decryption/
来源:APP全栈技术分享
文章版权归作者所有,未经允许请勿转载。
THE END
0
二维码
打赏
海报
关于Java中RSA加签解签,私钥加密公钥解密和公钥加密私钥解密代码详解
关于Java中RSA加签解签,私钥加密公钥解密和公钥加密私钥解密,一般为了安全采用的是
私钥加签,公钥验签
本地私钥加密,远程公钥解密(公钥可以用Base64转换……
文章目录
关闭
共有 0 条评论