云自无心水自闲

天平山上白云泉,云自无心水自闲。何必奔冲山下去,更添波浪向人间!
posts - 288, comments - 524, trackbacks - 0, articles - 6
  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

openpgp 验证签名

Posted on 2015-12-11 21:40 云自无心水自闲 阅读(1230) 评论(0)  编辑  收藏 所属分类: Java心得体会密码
在我的上一篇文章中介绍了如何进行GPG加密解密。http://www.blogjava.net/usherlight/archive/2014/12/10/421238.html
加密解密的基本操作流程是,用户使用公钥对明文进行加密,解密方使用私钥对密文进行解密。 

在实际应用中,除了加密保证文本内容不泄露外,同时还要考虑能够验证密文发送方的身份,比较普遍使用的方法就是签名。
本文主要对具体的方法进行介绍并附上源代码。
举例说明:
有用户张三需要发送文本给李四,首先张三会生成一对公钥1和私钥1,张三自己保留私钥1,并把公钥1发送给李四用于加密。
现在的问题是张三在收到一份密文的时候,如何能够确保这份密文是由李四而不是王五发的。
实现这个的过程我们称之为签名。
流程如下:李四也需要生成一对公钥2和私钥2,李四保留私钥2,把公钥2发给张三。

李四在发送密文的时候,除了使用公钥1进行加密,还需要使用私钥2进行签名。
张三在收到密文后,队了使用私钥1进行解密,还需要使用公钥2进行签名验证。

大致过程明白之后,可能会发现了一个问题,是先加密再签名好呢,不是先签名再加密?
推荐先签名再加密,因为先加密再签名可能会有一些安全上的小漏洞。详细的说明会比较长。
简单的说:签名并不能保证签名者知道密文的内容。
一个简单的小例子:小赵发了一个信息给管理员,内容如下:请把root密码告诉我。然后小赵用管理员的公钥进行了加密,然后用小赵自己的私钥进行了签名。
但是如果小钱截获了密文,他可以使用小赵的公钥去除掉签名,然后使用小钱的私钥进行签名,发给管理员。管理员收到加密签名的信息,就会把密码发给小钱。

验证签名的源代码:函数中的两个参数,第一个参数就是需要验证签名的内容输入流,第二个参数是公钥的输入流
 1 /*
 2  * verify the passed in file as being correctly signed.
 3  */
 4 private static void verifyFile(
 5     InputStream        in,
 6     InputStream        keyIn)
 7     throws Exception
 8 {
 9     in = PGPUtil.getDecoderStream(in);
10     JcaPGPObjectFactory            pgpFact = new JcaPGPObjectFactory(in);
11     PGPCompressedData           c1 = (PGPCompressedData)pgpFact.nextObject();
12     pgpFact = new JcaPGPObjectFactory(c1.getDataStream());           
13     PGPOnePassSignatureList     p1 = (PGPOnePassSignatureList)pgpFact.nextObject();
14     PGPOnePassSignature         ops = p1.get(0);
15     PGPLiteralData              p2 = (PGPLiteralData)pgpFact.nextObject();
16     InputStream                 dIn = p2.getInputStream();
17     int                         ch;
18     PGPPublicKeyRingCollection  pgpRing = new PGPPublicKeyRingCollection(PGPUtil.getDecoderStream(keyIn), new JcaKeyFingerprintCalculator());
19     PGPPublicKey                key = pgpRing.getPublicKey(ops.getKeyID());
20     FileOutputStream            out = new FileOutputStream(p2.getFileName());
21     ops.init(new JcaPGPContentVerifierBuilderProvider().setProvider("BC"), key);
22     while ((ch = dIn.read()) >= 0)
23     {
24         ops.update((byte)ch);
25         out.write(ch);
26     }
27     out.close();
28     PGPSignatureList            p3 = (PGPSignatureList)pgpFact.nextObject();
29     if (ops.verify(p3.get(0)))
30     {
31         System.out.println("signature verified.");
32     }
33     else
34     {
35         System.out.println("signature verification failed.");
36     }
37 }
38 



只有注册用户登录后才能发表评论。


网站导航: