验证规则
收到應答消息後,執行以下步驟進行簽名驗證
1) 使用正則表達式把應答報文分為兩部分:報文(request/response)部分和簽名(signature)部分;
2) 使用SHA256算法對報文(request/response)部分獲取消息摘要;
3) 使用公鑰將簽名解碼為消息摘要;
4) 比較第2,3步驟的消息摘要,如果相同,說明原文沒有變化,驗證通過;
Java代码实现
引用包:
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
生成簽名:
/**
* rsa2Sign:rsa2签名
*
* @author zhangh
* @param content
* @param privateKey
* @param charset
* @return
*/
public String signBySHA256WithRSA(String content, String privateKey, String charset){
if(StringUtils.isBlank(privateKey)){
//缺少签名私钥
return null;
}
try {
PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKey));
PrivateKey priKey = KeyFactory.getInstance("RSA").generatePrivate(priPKCS8);
Signature signature = Signature.getInstance("SHA256withRSA");
signature.initSign(priKey);
signature.update(content.getBytes(charset));
return Base64.encodeBase64String(signature.sign());
} catch (Exception e) {
//签名失败
return null;
}
}
驗證簽名:
public boolean verifyBySHA256WithRSA(String content, String sign, String publicKey, String charset){
//1) 使用正則表達式把應答報文分為兩部分:JSON格式的報文(request/response)部分和簽名(signature)部分,注意為保證原文順序,不能轉為JSON對象去操作;
//2) 使用SHA256算法對JSON格式的報文(request/response)部分獲取消息摘要;
//3) 使用公鑰將簽名解碼為消息摘要;
//4) 比較第2,3步驟的消息摘要,如果相同,說明原文沒有變化,驗證通過;
if (StringUtils.isBlank(publicKey)) {
//缺少验签公钥
return false;
}
try {
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(Base64.decodeBase64(publicKey));
PublicKey pubKey = KeyFactory.getInstance("RSA").generatePublic(keySpec);
Signature signature = Signature.getInstance("SHA256withRSA");
signature.initVerify(pubKey);
signature.update(content.getBytes(charset));
return signature.verify(Base64.decodeBase64(sign));
} catch (Exception e) {
//验签失败
return false;
}
}