天天看點

RSA加驗簽、加解密

apollo讀取本地配置,

修改C:\opt\settings目錄下的server.properties将env從DEV(開發環境)切換到(LOCAL)本地

RSA加驗簽、加解密

修改C:\opt\data\jp-cashier\config-cache目錄下

注:下圖檔案在第一次連接配接apollo就會在本地緩存伺服器上的配置

RSA加驗簽、加解密

将 valid.sign 屬性設定為true 即開啟驗簽

公私鑰儲存方式可分為證書檔案和資料庫,收銀台使用後者,故不贅述生成證書檔案過程。

加驗簽作用

    主要是鑒别請求是否為理想請求方發出的,請求的參數是否有被篡改。(商戶側------>收銀台)

操作步驟

  1. 商戶側生成公鑰和私鑰。
    RSA加驗簽、加解密
  2. 商戶側将公鑰告訴支付平台側友善其驗簽,私鑰則自行保留用以對關鍵的請求參數進行加簽,并生成對象的加簽串。
    RSA加驗簽、加解密

具體代碼實作

1.商戶側生成公私鑰

/**
 * 類職責:模拟商戶側生成公私鑰<br/>
 *    
 * <p>Title: CreateKeyPair.java</p>
 * <p>Description: </p>
 * <p>Copyright: </p>
 * <p>Company: </p>
 * 
 * <p>Author:Cent</p>
 * <p>CreateTime:2018年10月9日上午11:02:18
 */
public class CreateKeyPair {
 
    private final static int seed = 10;
 
    public static void main(String[] args) {
        KeyPairGenerator keyPairGenerator;
        try {
            keyPairGenerator = KeyPairGenerator.getInstance("RSA");
            keyPairGenerator.initialize(1024, new SecureRandom(new byte[seed]));
            KeyPair keyPair = keyPairGenerator.generateKeyPair();
             
            System.out.println("私鑰:"+new BASE64Encoder().encode(keyPair.getPrivate().getEncoded()));
            System.out.println("模數:"+((RSAPrivateKey) keyPair.getPrivate()).getModulus()
                    +"  \n指數:"+((RSAPrivateKey) keyPair.getPrivate()).getPrivateExponent()
                    +"  \nformat:"+keyPair.getPrivate().getFormat()+"\n");
             
            System.out.println("公鑰:"+new BASE64Encoder().encode(keyPair.getPublic().getEncoded()));
            System.out.println("系數:"+((RSAPublicKey) keyPair.getPublic()).getModulus()
                    +"  \n指數:"+((RSAPublicKey) keyPair.getPublic()).getPublicExponent()
                    +"  \nformat:"+keyPair.getPublic().getFormat());
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
 
    }
}
 
 
輸出結果:
私鑰:MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAJXCCq2qoOFukW1HsuoITCG8xboD
X5OSZDJykzNyTbWn0mhU8fD90A6qVgu9Tz681Ca3kMMbtTx/a/kXibZmW9yLsSO58y/zMCQH0nCJ
y8nlB6zB/bAY6LH15Jt13C+1CPXVXziA0V4aDiSqwwQMEAnzcU/OkGjq3QIC3g0ptsHhAgMBAAEC
gYApQB244HsYHWCpfUpm9Ioj8N918V/uQjCfRLgPP7jwBJ4MZvmNrBwXLgwth6PAYDr/vyh81bEC
TQbswfMI7wD2PonwhBl8/cK2x3a3G86Wfle5ANnTzrx2LUa8SBHDW5G1UzP/VJv/iP+2DR82Zv9B
O1I+HFSOXeLfs8W1u6DpEQJBANiNVfxjWCl8fjrBq/a1eZKlBSyKNkh8zkD5+SK90f/YME1kdHyf
YjJ1Fq2Oqa5odkAIVZoQ08Jp2rArz5pOhl8CQQCxCdZG6+RkOZFZYcqbvfXVDGKZGRqCFJOkn58b
uduBRaI8O5+Imdhv+bpAStKl9Js1bmcUo0f6M4rWgVJ5BR+/AkADIehAgl9gGkDpMKwAIZfkmyZ8
AnPOkJ+bKQKFkiFbhhEMzYsx0kxlVnRBhnLF5xTu0DAMznmBsm5LZhbWsJQZAkAcVZ+24CBArjoG
HTGpNYD35TCOokbs1NBAg8+aR2fLS9LIYx6IZV8PpN9bVN5b80c4CQB0fCGT+NXauP3zIo/PAkEA
m0Nd4p2Z0v/Znv6XVJOsGjDQw7XNTEhCHGMYp5ZTiouSU49UNfJVLQ6HatzlXoZF2Mzh6k4ZTT45
0yCWIHNLNw==
模數:105163626694518816415172421117660403192268789605824432907599620561348777360339014751042163331048173321651023563821307646759258716254356308513621614317501353410368313280970675848979425400380285065646715691914608847096136227967402458622860548093572063973039955235826589361562494454594915857926127411189010317793 
指數:28967053558897320199684034148893077169031786471219962202236726587629402153117168840285840554985452870934651835972080590190245790100609427976378189139868075432807327943932383568092468041316727581964572477862698058447469555034875489200425655065189656526378852092392684464864569898997243059671137410940934351121 
format:PKCS#8
 
公鑰:MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCVwgqtqqDhbpFtR7LqCEwhvMW6A1+TkmQycpMz
ck21p9JoVPHw/dAOqlYLvU8+vNQmt5DDG7U8f2v5F4m2Zlvci7EjufMv8zAkB9JwicvJ5Qeswf2w
GOix9eSbddwvtQj11V84gNFeGg4kqsMEDBAJ83FPzpBo6t0CAt4NKbbB4QIDAQAB
系數:105163626694518816415172421117660403192268789605824432907599620561348777360339014751042163331048173321651023563821307646759258716254356308513621614317501353410368313280970675848979425400380285065646715691914608847096136227967402458622860548093572063973039955235826589361562494454594915857926127411189010317793 
指數:65537 
format:X.509           

2.商戶側加簽

/**
 * 類職責:模拟商戶側加簽<br/>
 *    
 * <p>Title: InitSign.java</p>
 * <p>Description: </p>
 * <p>Copyright: </p>
 * <p>Company: </p>
 * 
 * <p>Author:Cent</p>
 * <p>CreateTime:2018年10月9日下午2:38:52
 */
public class InitSign {
    public static void main(String[] args) {
        String data = "待驗簽參數";
        String priKey = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAJXCCq2qoOFukW1HsuoITCG8xboD" +
                        "X5OSZDJykzNyTbWn0mhU8fD90A6qVgu9Tz681Ca3kMMbtTx/a/kXibZmW9yLsSO58y/zMCQH0nCJ" +
                        "y8nlB6zB/bAY6LH15Jt13C+1CPXVXziA0V4aDiSqwwQMEAnzcU/OkGjq3QIC3g0ptsHhAgMBAAEC" +
                        "gYApQB244HsYHWCpfUpm9Ioj8N918V/uQjCfRLgPP7jwBJ4MZvmNrBwXLgwth6PAYDr/vyh81bEC" +
                        "TQbswfMI7wD2PonwhBl8/cK2x3a3G86Wfle5ANnTzrx2LUa8SBHDW5G1UzP/VJv/iP+2DR82Zv9B" +
                        "O1I+HFSOXeLfs8W1u6DpEQJBANiNVfxjWCl8fjrBq/a1eZKlBSyKNkh8zkD5+SK90f/YME1kdHyf" +
                        "YjJ1Fq2Oqa5odkAIVZoQ08Jp2rArz5pOhl8CQQCxCdZG6+RkOZFZYcqbvfXVDGKZGRqCFJOkn58b" +
                        "uduBRaI8O5+Imdhv+bpAStKl9Js1bmcUo0f6M4rWgVJ5BR+/AkADIehAgl9gGkDpMKwAIZfkmyZ8" +
                        "AnPOkJ+bKQKFkiFbhhEMzYsx0kxlVnRBhnLF5xTu0DAMznmBsm5LZhbWsJQZAkAcVZ+24CBArjoG" +
                        "HTGpNYD35TCOokbs1NBAg8+aR2fLS9LIYx6IZV8PpN9bVN5b80c4CQB0fCGT+NXauP3zIo/PAkEA" +
                        "m0Nd4p2Z0v/Znv6XVJOsGjDQw7XNTEhCHGMYp5ZTiouSU49UNfJVLQ6HatzlXoZF2Mzh6k4ZTT45" +
                        "0yCWIHNLNw==";
         
        try {
            PrivateKey privateKey = Test2.getPrivateKey(priKey);
            Signature signature = Signature.getInstance("Sha1WithRSA");
            signature.initSign(privateKey);
            signature.update(data.getBytes("UTF-8"));
            byte[] signed = signature.sign();
            System.out.println("加簽串:"+new BASE64Encoder().encode(signed));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
 
    public static PrivateKey getPrivateKey(String key) throws Exception {
        byte[] keyBytes = (new BASE64Decoder()).decodeBuffer(key);
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
        return privateKey;
    }
 
}
 
 
輸出結果:
加簽串:dydmSfb4Y3bKrytKLO3e2hr84zcl118N1YOc1hsFt3OhFuNM7XhEsAL9SVJuOyD9dsn+EMxxxhWU
kogxNGkVbB3Eu5czmTM31KC9twG5jLR0UzhaopsaSGUezAoO7erf4EYGHqabPzA9jmyiU1KLabdU
flswEesu2chpkQvlKOA=           

3.支付平台側驗簽

/**
 * 類職責:支付平台側驗簽<br/>
 *    
 * <p>Title: InitVerify.java</p>
 * <p>Description: </p>
 * <p>Copyright: </p>
 * <p>Company: </p>
 * 
 * <p>Author:Cent</p>
 * <p>CreateTime:2018年10月9日下午2:49:25
 */
public class InitVerify {
    public static void main(String[] args)
            throws NoSuchAlgorithmException, InvalidKeyException, UnsupportedEncodingException, SignatureException {
        String data = "待驗簽參數";
         
        String pubKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCVwgqtqqDhbpFtR7LqCEwhvMW6A1+TkmQycpMz" +
                "ck21p9JoVPHw/dAOqlYLvU8+vNQmt5DDG7U8f2v5F4m2Zlvci7EjufMv8zAkB9JwicvJ5Qeswf2w" +
                "GOix9eSbddwvtQj11V84gNFeGg4kqsMEDBAJ83FPzpBo6t0CAt4NKbbB4QIDAQAB";
         
        String signed = "dydmSfb4Y3bKrytKLO3e2hr84zcl118N1YOc1hsFt3OhFuNM7XhEsAL9SVJuOyD9dsn+EMxxxhWU" +
                "kogxNGkVbB3Eu5czmTM31KC9twG5jLR0UzhaopsaSGUezAoO7erf4EYGHqabPzA9jmyiU1KLabdU" +
                "flswEesu2chpkQvlKOA=";
        try {
             
            /**
             * 驗簽過程
             */
            PublicKey publicKey = Test2.getPublicKey(pubKey);
            Signature signature2 = Signature.getInstance("Sha1WithRSA");
            signature2.initVerify(publicKey);
            signature2.update(data.getBytes("UTF-8"));
            boolean verify = signature2.verify(new BASE64Decoder().decodeBuffer(signed));
            System.out.println("驗簽結果:" + verify);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
 
 
    public static PublicKey getPublicKey(String key) throws Exception {
        byte[] keyBytes = new BASE64Decoder().decodeBuffer(key);
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PublicKey publicKey = keyFactory.generatePublic(keySpec);
        return publicKey;
    }
}
 
 
驗簽結果:true           

加解密作用

    對請求參數加密,非明文方式傳輸。(商戶側----→收銀台)

操作步驟

  1. 支付平台側生成公鑰和私鑰。
    RSA加驗簽、加解密
  2. 支付平台側将公鑰告訴商戶側友善其加密,私鑰則自行保留用以對關鍵的請求參數進行解密。
    RSA加驗簽、加解密

部分加解密代碼

String data="待加密參數。";
//對待加密的資料進行加密
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE,publicKey);
byte[] bytesEncrypt = cipher.doFinal(data.getBytes());
//Base64編碼
byte[] encodeBase64 = Base64.getEncoder().encode(bytesEncrypt);
System.out.println("加密後的資料:"+new String(encodeBase64));
 
byte[] bytesDecode = Base64.getDecoder().decode(encodeBase64);
//解密
Cipher cipher2=Cipher.getInstance("RSA");
cipher2.init(Cipher.DECRYPT_MODE,privateKey);
byte[] bytesDecrypt = cipher2.doFinal(bytesDecode);
System.out.println("解密後的資料:"+new String(bytesDecrypt));           

總結:公鑰加密,私鑰解密,私鑰加簽,公鑰解簽。

繼續閱讀