建行專線銀企直連秘鑰交互開發過程記錄


最近公司需要對接建行的專線直連,在開發過程遇到了一些坑,在此記錄並貼出完整代碼。

本篇文章主要是記錄如何生成我方的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