java中PFX与CER的使用(下)

续上篇的PFX加密使用,继续CER的使用。
对数据进行加密之后还需要对加密的数据解密操作,一般这种解密的操作发生在合作方,我们需要把生成的公钥以邮件的方式发送给合作方,合作方在收到公钥之后就可以对加密的数据进行解密操作了,示例如下:


	/**
	 * 指定Cer公钥路径解密
	 * 
	 * @param src
	 * @param pubCerPath
	 * @return
	 */
	public static String decryptByPubCerFile(String src, String pubCerPath) {
		PublicKey publicKey = getPublicKeyFromFile(pubCerPath);
		if (publicKey == null) {
			return null;
		}
		return decryptByPublicKey(src, publicKey);
	}
	/**
	 * 根据Cer文件读取公钥
	 * 
	 * @param pubCerPath
	 * @return
	 */
	public static PublicKey getPublicKeyFromFile(String pubCerPath) {
		FileInputStream pubKeyStream = null;
		try {
			pubKeyStream = new FileInputStream(pubCerPath);
			byte[] reads = new byte[pubKeyStream.available()];
			pubKeyStream.read(reads);
			return getPublicKeyByText(new String(reads));
		} catch (FileNotFoundException e) {
			// //log.error("公钥文件不存在:", e);
		} catch (IOException e) {
			// log.error("公钥文件读取失败:", e);
		} finally {
			if (pubKeyStream != null) {
				try {
					pubKeyStream.close();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
		return null;
	}

	/**
	 * 根据公钥Cer文本串读取公钥
	 * 
	 * @param pubKeyText
	 * @return
	 */
	public static PublicKey getPublicKeyByText(String pubKeyText) {
		try {
			CertificateFactory certificateFactory = CertificateFactory.getInstance(RsaConst.KEY_X509);
			BufferedReader br = new BufferedReader(new StringReader(pubKeyText));
			String line = null;
			StringBuilder keyBuffer = new StringBuilder();
			while ((line = br.readLine()) != null) {
				if (!line.startsWith("-")) {
					keyBuffer.append(line);
				}
			}
			Certificate certificate = certificateFactory.generateCertificate(new ByteArrayInputStream(new BASE64Decoder().decodeBuffer(keyBuffer.toString())));
			return certificate.getPublicKey();
		} catch (Exception e) {
			// log.error("解析公钥内容失败:", e);
		}
		return null;
	}

	/**
	 * 根据公钥解密
	 * 
	 * @param src
	 * @param publicKey
	 * @return
	 */
	public static String decryptByPublicKey(String src, PublicKey publicKey) {

		try {
			byte[] destBytes = rsaByPublicKey(FormatUtil.hex2Bytes(src), publicKey, Cipher.DECRYPT_MODE);
			if (destBytes == null) {
				return null;
			}
			return new String(destBytes, RsaConst.ENCODE);
		} catch (UnsupportedEncodingException e) {
//			//log.error("解密内容不是正确的UTF8格式:", e);
		}
		return null;
	}
	/**
	 * 公钥算法
	 * 
	 * @param srcData
	 *            源字节
	 * @param publicKey
	 *            公钥
	 * @param mode
	 *            加密 OR 解密
	 * @return
	 */
	public static byte[] rsaByPublicKey(byte[] srcData, PublicKey publicKey, int mode) {
		try {
			Cipher cipher = Cipher.getInstance(RsaConst.RSA_CHIPER);
			cipher.init(mode, publicKey);
			// 分段加密						
			int blockSize = (mode == Cipher.ENCRYPT_MODE) ? cipher.getOutputSize(srcData.length)-11 : cipher.getOutputSize(srcData.length);			
			byte[] encryptedData = null;
			for (int i = 0; i < srcData.length; i += blockSize) {
				// 注意要使用2的倍数,否则会出现加密后的内容再解密时为乱码
				byte[] doFinal = cipher.doFinal(subarray(srcData, i, i + blockSize));
				encryptedData = addAll(encryptedData, doFinal);
			}
			return encryptedData;

		} catch (NoSuchAlgorithmException e) {
			System.out.println("公钥算法-不存在的解密算法:");
		} catch (NoSuchPaddingException e) {
			System.out.println("公钥算法-无效的补位算法:");
		} catch (IllegalBlockSizeException e) {
			System.out.println("公钥算法-无效的块大小:");
		} catch (BadPaddingException e) {
			System.out.println("公钥算法-补位算法异常:");
			e.printStackTrace();
		} catch (InvalidKeyException e) {
			System.out.println("公钥算法-无效的私钥:");
		}
		return null;
	}

示例中的 subarray和addAll方法已经在上篇示例中。
配合PFX的加密整体使用为:


public static void main(String[] args) throws CertificateException {

System.out.println("加密前:111");
        String origData = new String(SecurityUtil.Base64Encode("111"));

        String encryptData = RsaCodingUtil.encryptByPriPfxFile(origData,
                "D:/home/user1/keyfile/Prv.pfx", "123456");
        System.out.println("加密后:"+encryptData);
        String reslut = RsaCodingUtil.decryptByPubCerFile(encryptData, "D:/home/user1/keyfile/puk.cer");
        reslut = SecurityUtil.Base64Decode(reslut);
        System.out.println("解密后:"+reslut);


}

输出结果:
在这里插入图片描述
已经完成对数据的加解密工作了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值