您的位置:首页 > 其它

数字签名及验证

2017-04-08 11:59 95 查看
由于项目需要用到数字签名,所以就上网查看了一些资料,随便找就是一大堆,说的也都差不多,自己写写关于数字签名这块记录,当做笔记吧.

首先说几个概念签名与加密.可以参考这个博客https://my.oschina.net/u/916545/blog/653201

签名的模式主要是:    1、甲方构造密钥对(公钥+私钥),并且将公钥给乙方

  2、甲方使用私钥对数据进行签名,然后将“签名+数据” 发送给乙方 

  3、乙方使用公钥+数字签名 验证数据

这里不多说了直接上代码解释

//数字签名,密钥算法
public static final String KEY_ALGORITHM="RSA";

/**
* 数字签名
* 签名/验证算法
* */
public static final String SIGNATURE_ALGORITHM="SHA1withRSA";

/**
* RSA密钥长度,RSA算法的默认密钥长度是1024
* 密钥长度必须是64的倍数,在512到65536位之间
* */
private static final int KEY_SIZE=1024;
//公钥
private static final String PUBLIC_KEY="RSAPublicKey";
//私钥
private static final String PRIVATE_KEY="RSAPrivateKey";

/**
* 获取私钥 传入bese64String字符串
* */
public static PrivateKey getPrivateKey(String privateKeyBase64Str) throws Exception{
//取得私钥Base64.decode(privateKeyBase64Str,Base64.DEFAULT)
PKCS8EncodedKeySpec sPkcs8KeySpec= new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKeyBase64Str));

KeyFactory keyFactory=KeyFactory.getInstance(KEY_ALGORITHM);
//生成私钥
return keyFactory.generatePrivate(sPkcs8KeySpec);
}

/**
* 签名
* @param content
* 待签名数据
* @param privateKeyBase64Str 密钥
* @return byte[] 数字签名
* */
public static String sign(String content,String privateKeyBase64Str) throws Exception{
System.out.println(Base64.class);
//取得私钥Base64.decode(privateKeyBase64Str,Base64.DEFAULT)
PKCS8EncodedKeySpec sPkcs8KeySpec= new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKeyBase64Str.getBytes()));
KeyFactory keyFactory=KeyFactory.getInstance(KEY_ALGORITHM);
PrivateKey privateKey = keyFactory.generatePrivate(sPkcs8KeySpec);
//实例化Signature
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
//初始化Signature
signature.initSign(privateKey);
//更新
signature.update(content.getBytes());
// return signature.sign(); //

String Signh=new String(Hex.encodeHex(signature.sign())) ;

return Signh;
}

/* public static byte[] sign(String content,PrivateKey privateKey) throws Exception{
//实例化Signature
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
//初始化Signature
signature.initSign(privateKey);
//更新
signature.update(content.getBytes());

4000
return signature.sign(); //
}*/

//*----------------------------------------------------------*//

public static PublicKey getPublicKey(String publicKeyBase64Str ) throws Exception{
//转换公钥材料
//实例化密钥工厂
KeyFactory keyFactory=KeyFactory.getInstance(KEY_ALGORITHM);
//初始化公钥
//密钥材料转换
X509EncodedKeySpec x509KeySpec=new X509EncodedKeySpec(Base64.decodeBase64(publicKeyBase64Str));
//产生公钥
PublicKey pubKey=keyFactory.generatePublic(x509KeySpec);
return pubKey;
}

/**
* 校验数字签名
* @param content 待校验数据
* @param publicKey 公钥
* @param signHexStr 数字签名
* @return boolean 校验成功返回true,失败返回false
* */
public static boolean verify(String content,String signHexStr,PublicKey publicKey) throws Exception{
//实例化Signature
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
//初始化Signature
signature.initVerify(publicKey);
//更新
signature.update(content.getBytes());
//验证
return signature.verify(Hex.decodeHex(signHexStr.toCharArray()));
}
public static boolean verify(String content,String signHexStr,String publicKeyBase64Str ) throws Exception{
//转换公钥材料
//实例化密钥工厂
KeyFactory keyFactory=KeyFactory.getInstance(KEY_ALGORITHM);
//初始化公钥//密钥材料转换
X509EncodedKeySpec x509KeySpec=new X509EncodedKeySpec(Base64.decodeBase64(publicKeyBase64Str.getBytes()));
//产生公钥
PublicKey pubKey=keyFactory.generatePublic(x509KeySpec);

//实例化Signature
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
//初始化Signature
signature.initVerify(pubKey);
//更新
signature.update(content.getBytes());
//验证
return signature.verify(Hex.decodeHex(signHexStr.toCharArray()));
}

这里我是直接从存储介质上拿到的私钥,私钥是后台给我的,
我使用私钥进行数字签名,后台进行验证,但后台在使用时指定了一些规定导致我一直解不出来,最后使用


Commons Codecjar包,

从上可以看到在拿到prikey(存储介质读取),使用sign方法进行签名,需要对传入的privateKeyBase64Str进行解码,由于一直使用安卓base64Api无法解出正确格式,使用commons code-jar包,里面的base64就可正常,弹药注意使用正确的方法,要不然会报没有此方法,Base64.decodeBase64(privateKeyBase64Str)就不行了
其他方法类似
签名验证就使用verify方法.初次写博客还有许多不懂的,上面的内容也是仅供参考,如果有不对的请帮我指出,感谢大家.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: