2 lin lucky lin_lucky 于 2016.01.26 20:08 提问

ping++ java验签(签名,公钥,charge)怎么获取

这是官网demo

 package example;

import java.io.FileInputStream;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.security.Signature;
import java.security.SignatureException;
import java.security.spec.X509EncodedKeySpec;

import org.apache.commons.codec.binary.Base64;

import Decoder.BASE64Decoder;

/**
 * Created by sunkai on 15/5/19. webhooks 验证签名示例
 * 
 * 该实例演示如何对 ping++ webhooks 通知进行验证。
 * 验证是为了让开发者确认该通知来自 ping++ ,防止恶意伪造通知。用户如果有别的验证机制,可以不进行验证签名。
 * 
 * 验证签名需要 签名、公钥、验证信息,该实例采用文件存储方式进行演示。
 * 实际项目中,需要用户从异步通知的 HTTP header 中读取签名,从 HTTP body 中读取验证信息。公钥的存储方式也需要用户自行设定。
 * 
 *  该实例仅供演示如何验证签名,请务必不要直接 copy 到实际项目中使用。
 * 
 */
public class WebHooksVerifyExample {
    private static String filePath = "src/my-server.pub";
    private static String eventPath = "src/charge";
    private static String signPath = "src/sign";

    /**
     * 验证webhooks 签名,仅供参考
     * @param args
     * @throws Exception
     */
    public static void main(String[] args) throws Exception {

        boolean result = verifyData(getByteFromFile(eventPath, false), getByteFromFile(signPath, true), getPubKey());
        System.out.println("验签结果:"+result);
    }

    /**
     * 读取文件,部署web程序的时候,签名和验签内容需要从request中获得
     * @param file
     * @param base64
     * @return
     * @throws Exception
     */
    public static byte[] getByteFromFile(String file, boolean base64) throws Exception {
        FileInputStream in = new FileInputStream(file);
        byte[] fileBytes = new byte[in.available()];
        in.read(fileBytes);
        in.close();
        String pubKey = new String(fileBytes, "UTF-8");
        if (base64) {
            BASE64Decoder decoder = new BASE64Decoder();
            fileBytes = decoder.decodeBuffer(pubKey);
//          fileBytes = Base64.decodeBase64(pubKey);
        }
        return fileBytes;
    }

    /**
     * 获得公钥
     * @return
     * @throws Exception
     */
    public static PublicKey getPubKey() throws Exception {
        // read key bytes
        FileInputStream in = new FileInputStream(filePath);
        byte[] keyBytes = new byte[in.available()];
        in.read(keyBytes);
        in.close();

        String pubKey = new String(keyBytes, "UTF-8");
        pubKey = pubKey.replaceAll("(-+BEGIN PUBLIC KEY-+\\r?\\n|-+END PUBLIC KEY-+\\r?\\n?)", "");

        keyBytes = Base64.decodeBase64(pubKey);

        // generate public key
        X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PublicKey publicKey = keyFactory.generatePublic(spec);
        return publicKey;
    }

    /**
     * 验证签名
     * @param data
     * @param sigBytes
     * @param publicKey
     * @return
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeyException
     * @throws SignatureException
     */
    public static boolean verifyData(byte[] data, byte[] sigBytes, PublicKey publicKey) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException {
        Signature signature = Signature.getInstance("SHA256withRSA");
        signature.initVerify(publicKey);
        signature.update(data);
        return signature.verify(sigBytes);
    }

}

2个回答

devmiao
devmiao   Ds   Rxr 2016.01.26 23:55
lin_lucky
lin_lucky 我现在能获取到签名和公钥但是验证签名返回false,不知道怎么回事
接近 2 年之前 回复
lin_lucky
lin_lucky 看不太懂,上面demo的验证签名是怎么验证的
接近 2 年之前 回复
pingplusplus_payment
pingplusplus_payment   2016.01.28 13:08

webhooks的验证签名:
verifyData(byte[] data, byte[] sigBytes, PublicKey publicKey)中
data:验证数据(Ping++webhooks返回的通知,这个是一个Json对象,你不用关心这个)(getByteFromFile(eventPath, false))
sigBytes:response header里的签名 getByteFromFile(signPath, true)
pubkey:Ping++管理平台“Ping++公钥”(getPubKey() 可以获取)

你可以直接run这个main方法

lin_lucky
lin_lucky 问题解决了,你这样是对的,就是文档里面没有说在哪获取这个eventpath,后来知道是webhooks传过来的charge,我拿event去toSting数据出错了,应该用buffer.toString()才对
接近 2 年之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!