/* * FileName:RSACoder.java *

* Copyright (c) 2017-2020, hermit (794890569@qq.com). *

* Licensed under the GNU General Public License, Version 3 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at *

* http://www.gnu.org/licenses/gpl-3.0.html *

* Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package cn.com.lzt.common.util.coder; import cn.com.lzt.common.util.security.SecurityCoder; import javax.crypto.Cipher; import java.security.*; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.HashMap; import java.util.Map; /** * RSA安全编码组件 * * @author ShenHuaJie * @version 1.0 * @since 1.0 */ public abstract class RSACoder extends SecurityCoder { /** * 数字签名 密钥算法 */ public static final String KEY_ALGORITHM = "RSA"; /** * 数字签名 签名/验证算法 */ public static final String SIGNATURE_ALGORITHM = "SHA1withRSA"; /** * 公钥 */ private static final String PUBLIC_KEY = "RSAPublicKey"; /** * 私钥 */ private static final String PRIVATE_KEY = "RSAPrivateKey"; /** * RSA密钥长度 默认1024位, 密钥长度必须是64的倍数, 范围在512至65536位之间。 */ private static final int KEY_SIZE = 512; /** * 签名 * * @param data 待签名数据 * @param privateKey 私钥 * @return byte[] 数字签名 * @throws Exception */ public static byte[] sign(byte[] data, byte[] privateKey) throws Exception { // 转换私钥材料 PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(privateKey); // 实例化密钥工厂 KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); // 取私钥匙对象 PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec); // 实例化Signature Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM); // 初始化Signature signature.initSign(priKey); // 更新 signature.update(data); // 签名 return signature.sign(); } /** * 校验 * * @param data 待校验数据 * @param publicKey 公钥 * @param sign 数字签名 * @return boolean 校验成功返回true 失败返回false * @throws Exception */ public static boolean verify(byte[] data, byte[] publicKey, byte[] sign) throws Exception { // 转换公钥材料 X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKey); // 实例化密钥工厂 KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); // 生成公钥 PublicKey pubKey = keyFactory.generatePublic(keySpec); // 实例化Signature Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM); // 初始化Signature signature.initVerify(pubKey); // 更新 signature.update(data); // 验证 return signature.verify(sign); } /** * 私钥解密 * * @param data 待解密数据 * @param key 私钥 * @return byte[] 解密数据 * @throws Exception */ public static byte[] decryptByPrivateKey(byte[] data, byte[] key) throws Exception { // 取得私钥 PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(key); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); // 生成私钥 PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec); // 对数据解密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, privateKey); return cipher.doFinal(data); } /** * 公钥解密 * * @param data 待解密数据 * @param key 公钥 * @return byte[] 解密数据 * @throws Exception */ public static byte[] decryptByPublicKey(byte[] data, byte[] key) throws Exception { // 取得公钥 X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(key); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); // 生成公钥 PublicKey publicKey = keyFactory.generatePublic(x509KeySpec); // 对数据解密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, publicKey); return cipher.doFinal(data); } /** * 公钥加密 * * @param data 待加密数据 * @param key 公钥 * @return byte[] 加密数据 * @throws Exception */ public static byte[] encryptByPublicKey(byte[] data, byte[] key) throws Exception { // 取得公钥 X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(key); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); PublicKey publicKey = keyFactory.generatePublic(x509KeySpec); // 对数据加密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE, publicKey); return cipher.doFinal(data); } /** * 私钥加密 * * @param data 待加密数据 * @param key 私钥 * @return byte[] 加密数据 * @throws Exception */ public static byte[] encryptByPrivateKey(byte[] data, byte[] key) throws Exception { // 取得私钥 PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(key); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); // 生成私钥 PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec); // 对数据加密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE, privateKey); return cipher.doFinal(data); } /** * 取得私钥 * * @param keyMap * @return * @throws Exception */ public static byte[] getPrivateKey(Map keyMap) throws Exception { Key key = (Key) keyMap.get(PRIVATE_KEY); return key.getEncoded(); } /** * 取得公钥 * * @param keyMap * @return * @throws Exception */ public static byte[] getPublicKey(Map keyMap) throws Exception { Key key = (Key) keyMap.get(PUBLIC_KEY); return key.getEncoded(); } /** * 初始化密钥 * * @return Map 密钥对儿 Map * @throws Exception */ public static Map initKey() throws Exception { // 实例化密钥对儿生成器 KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM); // 初始化密钥对儿生成器 keyPairGen.initialize(KEY_SIZE); // 生成密钥对儿 KeyPair keyPair = keyPairGen.generateKeyPair(); // 公钥 RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); // 私钥 RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); // 封装密钥 Map keyMap = new HashMap(2); keyMap.put(PUBLIC_KEY, publicKey); keyMap.put(PRIVATE_KEY, privateKey); return keyMap; } }