建行专线银企直连秘钥交互开发过程记录


最近公司需要对接建行的专线直连,在开发过程遇到了一些坑,在此记录并贴出完整代码。

本篇文章主要是记录如何生成我方的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();
        }
    }
}

  


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM