RSA加密、解密、签名(非对称加密)

本文介绍RSA非对称加密算法的基本原理及其实现方法,包括公钥和私钥的生成、加密解密过程以及签名验证流程。适用于支付场景中确保数据传输的安全性和真实性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

说明:
RSA为非对称加密,用于加密和解密,分为公钥和私钥。例如:app发起支付时,使用公钥对订单串进行加密,然后将加密订单串传给服务器,服务器使用私钥进行解密,验证数据的真实性。

使用:

public class RSAUtil {
	private static final String algorithm = "RSA";
	private static final String signature_algorithm = "MD5withRSA";
	private static final String KEY_PUBLIC = "PublicKey";
	private static final String KEY_PRIVATE = "PrivateKey";

	/**
	 * 生成公钥串、私钥串
	 * 
	 * @return Base64编码过的公钥串、Base64编码过的私钥串
	 */
	public static Map<String, String> generatorKey() {
		Map<String, String> map = new HashMap<String, String>();
		try {
			KeyPairGenerator keygen = KeyPairGenerator.getInstance(algorithm);
			// 创建随机产生器
			SecureRandom secureRandom = new SecureRandom();
			secureRandom.setSeed("abcdefg".getBytes());
			keygen.initialize(1024, secureRandom);
			KeyPair keys = keygen.genKeyPair();
			// 生成公钥
			RSAPublicKey publicKey = (RSAPublicKey) keys.getPublic();
			map.put(KEY_PUBLIC, Base64.encode(publicKey.getEncoded()));
			// 生成私钥
			RSAPrivateKey privateKey = (RSAPrivateKey) keys.getPrivate();
			map.put(KEY_PRIVATE, Base64.encode(privateKey.getEncoded()));
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
		return map;
	}

	/**
	 * 用私钥对订单串进行加密
	 * 
	 * @param orderInfo 未加密订单原串
	 * @param privateKey Base64编码过的私钥串
	 * 
	 * @return Base64编码过的已加密订单串
	 */
	public static String encrypt(String orderInfo, String privateKeyStr) {
		try {
			// 根据私钥byte[]创建PKCS8EncodedKeySpec对象
			PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(Base64.decode(privateKeyStr));
			// 指定RSA加密算法
			KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
			// 取得私钥对象
			PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec);
			// 对订单串加密并Base64编码
			Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
			cipher.init(Cipher.ENCRYPT_MODE, priKey);
			return Base64.encode(cipher.doFinal(orderInfo.getBytes()));
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 用公钥对订单串进行解密
	 * 
	 * @param orderInfo Base64编码过的已加密订单串
	 * @param publicKey Base64编码过的公钥串
	 * @param sign Base64编码过的签名串
	 * 
	 * @return 解密后的订单原串
	 */
	public static String decrypt(String orderInfo, String publicKeyStr) {
		try {
			// 根据公钥byte[]创建X509EncodedKeySpec对象
			X509EncodedKeySpec keySpec = new X509EncodedKeySpec(Base64.decode(publicKeyStr));
			// 指定RSA加密算法
			KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
			// 取公钥对象
			PublicKey pubKey = keyFactory.generatePublic(keySpec);
			// 对订单串解密
			Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
			cipher.init(Cipher.DECRYPT_MODE, pubKey);
			return new String(cipher.doFinal(Base64.decode(orderInfo)));
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	
	 /** 
     * 使用私钥对订单串进行签名 
     *  
     * @param orderInfo 未加密订单串 
     * @param privateKey Base64编码过的私钥串 
     *  
     * @return Base64编码过的签名串 
     */  
	public static String generatorSign(String orderInfo, String privateKey) {
		try {
			// 根据私钥byte[]创建PKCS8EncodedKeySpec对象
			PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(Base64.decode(privateKey));
			// 指定RSA加密算法
			KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
			// 取得私钥对象
			PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec);
			// 用私钥对订单串进行签名
			Signature signature = Signature.getInstance(signature_algorithm);
			signature.initSign(priKey);
			signature.update(orderInfo.getBytes());
			// 对私钥进行Base64编码
			return Base64.encode(signature.sign());
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

    /** 
     * 使用公钥校验签名 
     *  
     * @param orderInfo 未加密订单串 
     * @param publicKey Base64编码过的公钥串 
     * @param sign Base64编码过的签名串 
     *  
     * @return 校验成功返回true, 校验失败返回false 
     */  
	public static boolean verifySign(String orderInfo, String publicKey, String sign) {
		try {
			// 根据公钥byte[]创建X509EncodedKeySpec对象
			X509EncodedKeySpec keySpec = new X509EncodedKeySpec(Base64.decode(publicKey));
			// 指定RSA加密算法
			KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
			// 取公钥对象
			PublicKey pubKey = keyFactory.generatePublic(keySpec);
			// 根据公钥和待加密串初始化Signature
			Signature signature = Signature.getInstance(signature_algorithm);
			signature.initVerify(pubKey);
			signature.update(orderInfo.getBytes());
			// 根据公钥和订单串进行签名校验,通过表示正常,否则表示订单串是伪造的。
			return signature.verify(Base64.decode(sign));
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}

	public static void main(String[] args) {
//		// 产生公钥和私钥,保存起来下次使用
//		Map<String, String> keyMap = generatorKey();
//		// 获得公钥
//		String publicKey = keyMap.get(KEY_PUBLIC);
//		// 获得私钥
//		String privateKey = keyMap.get(KEY_PRIVATE);
//		System.err.println("公钥 : " + publicKey);
//		System.err.println("私钥 : " + privateKey);

		String privateKey = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAIb7h8RwIyvjF1bZPBid2W0ZSn3WXRTYJ4BW6niL1IZhlQVupFEyjFS1mpk6gU9g7InlZ350A/H9DWiX5hxOWunETecFTP5XfqbvyUTR5N6WErhdSkinrVFAaQSQOxn5ID8GhXg+iTsPzidAFAJ5sKIJ9OgwOL6d1ABrbBPydlMdAgMBAAECgYBvdRS3VK0GGR71fK0N2pFlb6O94pq7knyTkbFMVpHnYH4vnRubXHTZoZcFfXS2+d53QvDBTsTPNVe0DPFaYCzacNEvVYXiIg2tNM/3EmD/Zy8yn2ywmkcuA88upTOLftceJ8H7FQOFhxqwyAOMsn46MmnkFkfidDtEl3qOgm4uNQJBANy331/8gsRBUDMA//FlJXvFUaWY/hsrPltfHMUfMaMZi2z0nbTZ9q/hUXWOCZvS+QJsaKNx8qfWBftgkulQNz8CQQCcjzjCy3yEULR2vAk9lET1lH/UZ/1Jq2d9Dsaf+Bt5BBmHAvLZR6wiWYly8pqR8Zn7ncFnmmVcll45CnCQSVqjAkEAz3WE4BPYVd+OImKuL5eCw/OT6rMDJUZgNkIQKLhJT6STCLZkBblZxbdjebsoDO8gXsbHE9nm2xqwRLdhXyumwQJARZ+n1XEbAdjGOJts3JbIiBIvOu24BYAVeNcOW+vBg/Lfy1vzVc967Je2+YiMVuUD3pMMhJ9z/lXcty8+WdxVUwJASJgBFbNqoycbPByWW9sxuDwYBmZxr2+UCVnp/AynNGS3r/gTTIgbVIOEdEk1nHDbwXthxY4P5WAUGZm4KJNY5g==";
		String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCG+4fEcCMr4xdW2TwYndltGUp91l0U2CeAVup4i9SGYZUFbqRRMoxUtZqZOoFPYOyJ5Wd+dAPx/Q1ol+YcTlrpxE3nBUz+V36m78lE0eTelhK4XUpIp61RQGkEkDsZ+SA/BoV4Pok7D84nQBQCebCiCfToMDi+ndQAa2wT8nZTHQIDAQAB";
		// 待签名的订单串
		String orderInfo = "orderId=1001&price=10.1&desc=书本&num=1";

		// 加密订单串
		String encryptOrderInfo = encrypt(orderInfo, privateKey);
		System.err.println("加密后的订单串: " + encryptOrderInfo);
		// 解密订单串
		String decryptOrderInfo = decrypt(encryptOrderInfo, publicKey);
		System.err.println("解密后的订单串: " + decryptOrderInfo);

		// 使用私钥对订单串进行签名 
		String sign = generatorSign(orderInfo, privateKey);
		System.err.println("签名 : " + sign);
		// 使用公钥校验签名 
		boolean result = verifySign(orderInfo, publicKey, sign);
		System.err.println("签名校验结果: " + result);
	}
}

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值