Last active
October 30, 2019 02:04
-
-
Save pgkk/a0ac949acaaf261b7aacded27bf93ca8 to your computer and use it in GitHub Desktop.
DSA加密算法签名工具类(包含生成密钥,生成签名、校验签名等工具方法)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.xxx.util; | |
import com.alibaba.dubbo.common.json.JSON; | |
import org.apache.commons.codec.binary.Hex; | |
import org.springframework.util.StringUtils; | |
import sun.misc.BASE64Decoder; | |
import sun.misc.BASE64Encoder; | |
import java.security.*; | |
import java.security.interfaces.DSAPrivateKey; | |
import java.security.interfaces.DSAPublicKey; | |
import java.security.spec.PKCS8EncodedKeySpec; | |
import java.security.spec.X509EncodedKeySpec; | |
import java.util.Map; | |
import java.util.SortedMap; | |
import java.util.TreeMap; | |
/** | |
* DSA加密算法签名工具类 | |
*/ | |
public class DSAUtil { | |
public final static String SIGN_PARAM_KEY = "sign"; | |
public final static String CHAR_SET = "UTF-8"; | |
public final static String KEY_METHOD = "DSA"; | |
public final static String SIGNATURE = "SHA1withDSA"; | |
//test | |
public static void main(String[] args) { | |
SortedMap<String, String> map = new TreeMap<>(); | |
map.put("ApTransactionId","sdsdf323ss"); | |
map.put("ApId","aa"); | |
map.put("AppId","a323"); | |
map.put("PayCode","567"); | |
map.put("ApUserId","1ss"); | |
map.put("Bu","xx"); | |
map.put("Msisdn","37&434"); | |
try { | |
//创建密钥 | |
Key key = createKeys(); | |
System.out.println("生成的公钥和私钥:" + JSON.json(key)); | |
//生成签名 | |
Sign sign = genSign(map, key.getPrivateKey()); | |
System.out.println("参数源串:" + sign.getOriginal()); | |
System.out.println("签名串:" + sign.getSign()); | |
//验证签名 | |
boolean flag = verify(sign.getOriginal(), sign.getSign(), key.getPublicKey()); | |
System.out.println("验证结果:" + flag); | |
} catch (Exception e) { | |
e.printStackTrace(); | |
} | |
} | |
/** | |
* 生成密钥 | |
* @return | |
* @throws Exception | |
*/ | |
public static Key createKeys() throws Exception{ | |
//初始化密钥 | |
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KEY_METHOD); | |
keyPairGenerator.initialize(512); | |
KeyPair keyPair = keyPairGenerator.generateKeyPair(); | |
DSAPublicKey dsaPublicKey = (DSAPublicKey) keyPair.getPublic(); | |
DSAPrivateKey dsaPrivateKey = (DSAPrivateKey)keyPair.getPrivate(); | |
return new Key((new BASE64Encoder().encode(dsaPublicKey.getEncoded())), | |
(new BASE64Encoder().encode(dsaPrivateKey.getEncoded()))); | |
} | |
/** | |
* 生成签名 | |
* @param params 参数集合 | |
* @param priKey 私钥 | |
* @return | |
* @throws Exception | |
*/ | |
public static Sign genSign(SortedMap<String, String> params, String priKey) throws Exception{ | |
StringBuilder sb = new StringBuilder(); | |
boolean first = true; | |
for (Map.Entry<String, String> entry : params.entrySet()) { | |
//拼装参数,排除sign | |
if (!entry.getKey().equalsIgnoreCase(SIGN_PARAM_KEY)) { | |
if (!StringUtils.isEmpty(entry.getKey())){ | |
if(!first){ | |
sb.append("&"); | |
} | |
sb.append(entry.getKey()).append("=").append(entry.getValue()); | |
first = false; | |
} | |
} | |
} | |
String src = sb.toString(); | |
byte[] srcBytes = src.getBytes(CHAR_SET); | |
KeyFactory keyFactory = KeyFactory.getInstance(KEY_METHOD); | |
byte[] keyBytes = (new BASE64Decoder()).decodeBuffer(priKey); | |
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(keyBytes); | |
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec); | |
Signature signature = Signature.getInstance(SIGNATURE); | |
signature.initSign(privateKey); | |
signature.update(srcBytes); | |
byte[] result = signature.sign(); | |
String sign = Hex.encodeHexString(result); | |
return new Sign(src, sign); | |
} | |
/** | |
* 验证 | |
* @param src 源参数串 | |
* @param sign 签名串 | |
* @param pubKey 公钥 | |
* @return | |
*/ | |
public static boolean verify(String src, String sign, String pubKey) throws Exception{ | |
byte[] srcBytes = src.getBytes(CHAR_SET); | |
byte[] keyBytes = (new BASE64Decoder()).decodeBuffer(pubKey); | |
KeyFactory keyFactory = KeyFactory.getInstance(KEY_METHOD); | |
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); | |
PublicKey publicKey = keyFactory.generatePublic(keySpec); | |
Signature signature = Signature.getInstance(SIGNATURE); | |
signature.initVerify(publicKey); | |
signature.update(srcBytes); | |
return signature.verify(Hex.decodeHex(sign.toCharArray())); | |
} | |
/** | |
* 密钥 | |
*/ | |
public static class Key{ | |
private String publicKey; | |
private String privateKey; | |
public Key(){ | |
} | |
public Key(String publicKey, String privateKey) { | |
this.publicKey = publicKey; | |
this.privateKey = privateKey; | |
} | |
public String getPublicKey() { | |
return publicKey; | |
} | |
public void setPublicKey(String publicKey) { | |
this.publicKey = publicKey; | |
} | |
public String getPrivateKey() { | |
return privateKey; | |
} | |
public void setPrivateKey(String privateKey) { | |
this.privateKey = privateKey; | |
} | |
} | |
/** | |
* 签名 | |
*/ | |
public static class Sign{ | |
private String original; | |
private String sign; | |
public Sign(){ | |
} | |
public Sign(String original, String sign) { | |
this.original = original; | |
this.sign = sign; | |
} | |
public String getOriginal() { | |
return original; | |
} | |
public void setOriginal(String original) { | |
this.original = original; | |
} | |
public String getSign() { | |
return sign; | |
} | |
public void setSign(String sign) { | |
this.sign = sign; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment