今天头让我做一个数字签名,因为我是我们部门会java的而且我是实习生,所以这个艰(wu)巨(liao)的任务就华丽丽地落在了我身上。
At first,数字签名是啥?不知道,感觉像是把这个东西贴上标签,表明他是你的?应该大概也许可能是这个意思。头又说,就是那个报文,我需要给那个报文添加一个签名,对方就知道是我发的了,what?报文?报文又是毛线?网上传的那东西?算了,一样一样来。
果断问度娘和谷歌,数字签名,是电子身份的认证手段,标志网上实体的身份,what is 网上实体?难道就是头说的报文?数字签名是这样一个过程:
1. At first,一个字符串或者报文或者之类之类的网上实体,这个通信的双方使用约定的HASH算法计算得到一个固定位数的报文摘要(改变任何一位,重新计算的摘要值会不相符)-------------------------姐认同这一点,但是姐觉得很奇怪的是,为毛线,我相同的报文摘要仍然是不同的,而且每次生成的摘要还是相同的,而且验证结果还是正确的(姐用的是java的Signature),感觉跟时间相关????
2. then,将报文摘要值用发送者的私人密钥连同报文,数字证书(公钥)发送给接受者
3. 接受者接收到之后用同样的HASH算法对报文的摘要值用发送者的公开密钥进行比较,如果相等则说明报文来自发送者
4. 确认发送者的真实身份
其实都是挺理论,你不这么说人家也明白的一堆东西,实践是检验真理的唯一标准。
JDK提供了很多签名工具,keytool,jarsigner,policytool,姐实践过keytool和jarsinger,挺好用的,不难,懒得说了,也没用到~
这里主要用到了Java中的Signature类,这个类提供签名的方法和进行相关的验证
public static void main(String[] args) {
//获取key,这个key用于初始化签名
PrivateKey privateKey = (PrivateKey) getKeyObj("****************", false);
//签名之后的字符串
byte[] bb = null;
//签名类
Signature sig;
try {
//DSA是签名的一种算法
sig = Signature.getInstance("DSA");
//初始化签名
sig.initSign(privateKey);
//Test为需要进行签名的报文,update接受byte数组作为参数
sig.update("Test".getBytes());
//签名并且返回生成的数字签名
bb = sig.sign();
System.out.println("bb="+new String(bb));
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvalidKeyException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SignatureException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//对生成的数字签名进行base64加密编码
String enStr = StringUtil.getBASE64(bb).toString();
System.out.println("enStr="+enStr);
}
public static Object getKeyObj(String path, boolean isPuk){
FileInputStream fis_private;
ObjectInputStream ois_private;
Object obj =null;
String keyName ="";
if(isPuk){
keyName ="***************"+path+".public.key";
}else{
keyName = "*******************"+path+".private.key";
}
try {
fis_private = new FileInputStream(new File(keyName));
ois_private = new ObjectInputStream(fis_private);
obj = ois_private.readObject();
ois_private.close();
fis_private.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return obj;
}
其中,姐还有几点不懂的地方,不过不影响姐的正常使用,在这里做个记录,以后感兴趣继续研究:
1. 进行初始化的keyobject到底是什么东西,自动生成,网上下载还是什么特殊的途径得到?这个key主要是用来做什么的?
2. 公共密钥和私有密钥是啥区别?分别在什么情况下使用?
3. 为什么对于相同的字符串,每次生成的数字签名都不相同,是否跟时间相关?