最近公司需要对接建行的专线直连,在开发过程遇到了一些坑,在此记录并贴出完整代码。
本篇文章主要是记录如何生成我方的rsa公钥和rsa私钥,并将rsa公钥按建设银行的要求加密后提供给建设银行。
package x; import java.io.File; import java.io.FileOutputStream; import java.io.FileWriter; import java.io.IOException; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.text.SimpleDateFormat; import java.util.Date; import javax.crypto.Cipher; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.DESKeySpec; import org.apache.commons.codec.binary.Base64; public class RSADemo { public static void main(String[] args) throws Exception { // 生产RSA公私钥,并返回RSA公钥 String oriKey = genKeyPair(); // 电子银行合约编号(取后10位,不足10位的,前面补0)+交换当日日期(YYMMDD 6位) String desKey = getDESKey(); // 建行提供方法处理后8位byte[] byte[] keyByte = asc2bin(desKey); // 对RSA公钥加密 byte[] enc_data = encryptKey(oriKey, keyByte); // 返回建行byte字节流 byte[] bytes1 = "000000".getBytes(); byte[] allBytes = new byte[bytes1.length + enc_data.length]; System.arraycopy(bytes1, 0, allBytes, 0, bytes1.length); System.arraycopy(enc_data, 0, allBytes, bytes1.length, enc_data.length); //建行所需 saveFile(allBytes,"D:/CCBKEY/pubkey.dat"); System.out.println("allBytes即为建行所需,该byte[]长度:" + allBytes.length); // 对RSA公钥解密 String encodeDecryptKeyString = decryptKey(enc_data, keyByte); System.out.println("经加解密后与原RSA公钥是否相同:" + encodeDecryptKeyString.equals(oriKey)); } private static String getDESKey() { String customerId = "SZ44200009022220201"; // 电子银行合约编号取后10位,不足10位,前面补0 if (customerId.length() >= 10) { customerId = customerId.substring(customerId.length() - 10, customerId.length()); } else { customerId = "0000000000".substring(customerId.length()) + customerId; } // 交换当日日期(YYMMDD) SimpleDateFormat sdf = new SimpleDateFormat("yyMMdd"); String date = sdf.format(new Date()); // DES密钥 String DESKey = customerId + date; return DESKey; } private static byte[] asc2bin(String hexString) { byte[] hexbyte = hexString.getBytes(); byte[] bitmap = new byte[hexbyte.length / 2]; for (int i = 0; i < bitmap.length; i++) { hexbyte[i * 2] -= hexbyte[i * 2] > '9' ? 7 : 0; hexbyte[i * 2 + 1] -= hexbyte[i * 2 + 1] > '9' ? 7 : 0; bitmap[i] = (byte) ((hexbyte[i * 2] << 4 & 0xf0) | (hexbyte[i * 2 + 1] & 0x0f)); } return bitmap; } private static byte[] encryptKey(String in, byte[] key_byte) throws Exception { byte[] enc_data = null; SecretKeyFactory skf = SecretKeyFactory.getInstance("DES"); SecretKey secretkey = skf.generateSecret(new DESKeySpec(key_byte)); byte[] inByte = Base64.decodeBase64(in); Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, secretkey, new SecureRandom()); enc_data = cipher.doFinal(inByte); return enc_data; } private static String decryptKey(byte[] in, byte[] key_byte) throws Exception { byte[] dec_data = null; SecretKeyFactory skf = SecretKeyFactory.getInstance("DES"); SecretKey secretkey = skf.generateSecret(new DESKeySpec(key_byte)); Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding"); cipher.init(Cipher.DECRYPT_MODE, secretkey); dec_data = cipher.doFinal(in); String encodeDecryptKeyString = Base64.encodeBase64String(dec_data); return encodeDecryptKeyString; } private static String genKeyPair() throws Exception { // KeyPairGenerator类用于生成公钥和私钥对,基于RSA算法生成对象 KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA"); // 初始化密钥对生成器,密钥大小为96-1024位 keyPairGen.initialize(1024, new SecureRandom()); // 生成一个密钥对,保存在keyPair中 KeyPair keyPair = keyPairGen.generateKeyPair(); RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); // 得到公钥 RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); // 得到私钥 Base64 base64 = new Base64(); String publicKeyString = base64.encodeToString(publicKey.getEncoded()); saveFile(publicKey.getEncoded(),"D:/CCBKEY/gouxin_rsa_pri_byte.txt"); saveFile(publicKeyString,"D:/CCBKEY/gouxin_rsa_pub_base64.txt"); String privateKeyString = base64.encodeToString(privateKey.getEncoded()); saveFile(privateKey.getEncoded(),"D:/CCBKEY/gouxin_rsa_pub_byte.txt"); saveFile(privateKeyString,"D:/CCBKEY/gouxin_rsa_pub_base64.txt"); return publicKeyString; } /** * 保存文件 * @param fileString 文件内容 * @param filepath 文件绝对路径 */ public static void saveFile(String fileString, String filepath){ File file = new File(filepath); if (file.exists()) { file.delete(); } FileWriter writer; try { writer = new FileWriter(filepath); writer.write(fileString); writer.flush(); writer.close(); } catch (IOException e) { e.printStackTrace(); } } /** * 将字节流转换成文件 * @param data 二进制数据 * @param filepath 文件绝对路径 * @throws Exception */ public static void saveFile(byte[] data,String filepath)throws Exception { if (data != null) { File file = new File(filepath); if (file.exists()) { file.delete(); } FileOutputStream fos = new FileOutputStream(file); fos.write(data, 0, data.length); fos.flush(); fos.close(); } } }