2 数字签名

2024-05-01 12:38
文章标签 数字签名

本文主要是介绍2 数字签名,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

转载自:  http://blog.chinaunix.net/uid-7374279-id-4064434.html


基本原理:
    数字签名使用密钥对(公开密钥和私有密钥),任何持有公开密钥的人都能解密、而只有加密密钥持有者(私有密钥)能够生成消息。
使用举例:
    1. A生成一个非对称加密密钥,她用该密钥对明文进行加密。
    2. A将公开密钥以某种方式传递给B。
    3. A用私有密钥生成消息,发给B。
    4. B用公开密钥解密。B能够确认2点:1)原消息没有被篡改。2)是由A加密的,即发出人是A。
说明:
   Java生成密钥、保存密钥的实例源码,通过本源码可以了解到Java如何产生单钥加密的密钥(myKey)、产生双钥的密钥对(keyPair)、如何保存公钥的字节数组、保存私钥到文件privateKey.dat、如何用Java对象序列化保存私钥,通常应对私钥加密后再保存、如何从文件中得到公钥编码的字节数组、如何从字节数组解码公钥。
   最普通的公共密钥算法是Rivest, Shamir, 和 Adleman发明的RSA算法。直到2000年10月,该算法一直受RSA Security公司授予的专利保护。该专利的转让许可证价格昂贵,通常要支付3%的专利权使用费,每年至少付款50 000美元。现在该加密算法已经公开,Java SE 5.0及以后的版本都支持RSA算法。
注意:如果你使用的是旧版本的JDK,可以使用Legion of Bouncy Castle(网址http://www. bouncycastle.org),它提供了一个支持RSA的密码提供商和其他许多SunJCE提供商没有提供的特性。该提供商已经由Sun公司签名,因此可以将它与JDK结合起来使用。
http://hiyachen.blog.chinaunix.net  chf@tsinghua.org.cn http://weibo.com/u/1741045910 
如果要使用RSA算法,需要一对公共/私有密钥。你可以按如下方法使用KeyPairGenerator来获得:
KeyPairGenerator pairgen = KeyPairGenerator.getInstance("RSA");
SecureRandom random = new SecureRandom();
pairgen.initialize(KEYSIZE, random);
KeyPair keyPair = pairgen.generateKeyPair();
Key publicKey = keyPair.getPublic();
Key privateKey = keyPair.getPrivate();
列表9-18中的程序有三个选项。-genkey选项用于产生一个密钥对,-encrypt选项用于生成AES密钥,并且用公共密钥对其进行包装。
Key key = . . .; // an AES key
Key publicKey = . . .; // a public RSA key
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.WRAP_MODE, publicKey);
byte[] wrappedKey = cipher.wrap(key);
然后它便生成一个包含下列内容的文件:
包装过的密钥的长度
包装过的密钥字节
用AES密钥加密的明文
-decrypt选项用于对这样的文件进行解密。请试运行该程序,首先生成RSA密钥:
java RSATest -genkey public.key private.key
然后对一个文件进行加密:
java RSATest -encrypt plaintextFile encryptedFile public.key
最后,对文件进行解密,并且检验解密后的文件是否与明文相匹配。
java RSATest -decrypt encryptedFile decryptedFile private.key

RSATest.java
1. import java.io.*;
2. import java.security.*;
3. import javax.crypto.*;
4.
5. 
13. public class RSATest
14. {
15.    public static void main(String[] args)
16.    {
17.       try
18.       {
19.          if (args[0].equals("-genkey"))
20.          {
21.              KeyPairGenerator pairgen = KeyPairGenerator.getInstance("RSA");
22.              SecureRandom random = new SecureRandom();
23.              pairgen.initialize(KEYSIZE, random);
24.              KeyPair keyPair = pairgen.generateKeyPair();
25.              ObjectOutputStream out = new ObjectOutputStream (new FileOutputStream(args[1]));
26.              out.writeObject(keyPair.getPublic());
27.              out.close();
28.              out = new ObjectOutputStream(new FileOutputStream(args[2]));
29.              out.writeObject(keyPair.getPrivate());
30.              out.close();
31.          }
32.          else if (args[0].equals("-encrypt"))
33.          {
34.             KeyGenerator keygen = KeyGenerator.getInstance("AES");
35.             SecureRandom random = new SecureRandom();
36.             keygen.init(random);
37.             SecretKey key = keygen.generateKey();
38.
39.             // wrap with RSA public key
40.             ObjectInputStream keyIn = new ObjectInputStream
(new FileInputStream(args[3]));
41.             Key publicKey = (Key) keyIn.readObject();
42.             keyIn.close();
43.
44.             Cipher cipher = Cipher.getInstance("RSA");
45.             cipher.init(Cipher.WRAP_MODE, publicKey);
46.             byte[] wrappedKey = cipher.wrap(key);
47.             DataOutputStream out = new DataOutputStream
(new FileOutputStream(args[2]));
48.             out.writeInt(wrappedKey.length);
49.             out.write(wrappedKey);
50.
51.             InputStream in = new FileInputStream(args[1]);
52.             cipher = Cipher.getInstance("AES");
53.             cipher.init(Cipher.ENCRYPT_MODE, key);
54.             crypt(in, out, cipher);
55.             in.close();
56.             out.close();
57.          }
58.          else
59.          {
60.             DataInputStream in = new DataInputStream
(new FileInputStream(args[1]));
61.             int length = in.readInt();
62.             byte[] wrappedKey = new byte[length];
63.             in.read(wrappedKey, 0, length);
64.
65.             // unwrap with RSA private key
66.             ObjectInputStream keyIn = new ObjectInputStream
(new FileInputStream(args[3]));
67.             Key privateKey = (Key) keyIn.readObject();
68.             keyIn.close();
69.
70.             Cipher cipher = Cipher.getInstance("RSA");
71.             cipher.init(Cipher.UNWRAP_MODE, privateKey);
72.             Key key = cipher.unwrap(wrappedKey, "AES", Cipher.SECRET_KEY);
73.
74.             OutputStream out = new FileOutputStream(args[2]);
75.             cipher = Cipher.getInstance("AES");
76.             cipher.init(Cipher.DECRYPT_MODE, key);
77.
78.             crypt(in, out, cipher);
79.             in.close();
80.             out.close();
81.          }
82.       }
83.       catch (IOException e)
84.       {
85.          e.printStackTrace();
86.       }
87.       catch (GeneralSecurityException e)
88.       {
89.          e.printStackTrace();
90.       }
91.       catch (ClassNotFoundException e)
92.       {
93.          e.printStackTrace();
94.       }
95.    }
96.
97.    
104.    public static void crypt(InputStream in, OutputStream out, Cipher cipher)
105.          throws IOException, GeneralSecurityException
106.    {
107.       int blockSize = cipher.getBlockSize();
108.       int outputSize = cipher.getOutputSize(blockSize);
109.       byte[] inBytes = new byte[blockSize];
110.       byte[] outBytes = new byte[outputSize];
111.
112.       int inLength = 0;
113.       ;
114.       boolean more = true;
115.       while (more)
116.       {
117.          inLength = in.read(inBytes);
118.          if (inLength == blockSize)
119.          {
120.             int outLength = cipher.update(inBytes, 0, blockSize, outBytes);
121.             out.write(outBytes, 0, outLength);
122.          }
123.          else more = false;
124.       }
125.       if (inLength > 0) outBytes = cipher.doFinal(inBytes, 0, inLength);
126.       else outBytes = cipher.doFinal();
127.       out.write(outBytes);
128.    }
129.
130.    private static final int KEYSIZE = 512;
131. }
你现在已经看到了Java安全模型是如何允许我们去控制代码的执行的,这是Java平台的一个独一无二且越来越重要的方面。你已经看到了Java类库提供的认证和加密服务。但是我们没有涉及许多高级和专有的话题,比如有:
提供了对Kerberos协议进行支持的"通用安全服务"的GSS-API(原则上同样支持其他安全信息交换协议)。下面这个网址上有一份JDK的指南:
http://docs.oracle.com/javase/7/docs/technotes/guides/security/jgss/tutorials/index.html
对SASL的支持,SASL即简单认证和安全层,可以为LDAP和IMAP协议所使用。如果想在自己的应用程序中实现SASL,请浏览下面这个网址:
http://docs.oracle.com/javase/7/docs/technotes/guides/security/sasl/sasl-refguide.html
对SSL的支持,SSL即安全套接层。在HTTP上使用SSL对应用程序的编程人员是透明的,只需要直接使用以https开头的URL即可。如果想要给你的应用程序添加SSL支持,请参阅下面网址中的:JSSE(Java安全套接扩展)参考指南http://docs.oracle.com/javase/7/docs/technotes/guides/security/jsse/JSSERefGuide.html
全面了解java安全策略:http://docs.oracle.com/javase/7/docs/technotes/guides/security/index.html

这篇关于2 数字签名的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/951708

相关文章

cab数字签名制作

制作证书 makecert -$ "individual" -r /sv "Smart360.PVK" /n "CN= www.smart360.cn,E=15011116466-163-com,O=lilingtong " smart360.cer 制作inf cabarc.exe -s 6144 N smart.cab zlib.dll qnviccub.dll bridge

高级数字签名之椭圆曲线数字签名算法(ECDSA)

@TOC 1. 算法简述 该算法是微软操作系统及办公软件的序列号验证算法。 ECDSA(Elliptic Curve Digital Signature Algorithm, 椭圆曲线数字签名算法) 于1999年作为ANSI标准, 并于2000年成为IEEE和NIST标准。 ECDSA算法具有速度快、强度高、签名短等有点。 3. 代码实现 Java中未对该算法做实现, 而在Bouncy

数字签名标准算法——DSA

数字签名标准算法——DSA 1. 算法简述2.模型分析3. 代码实现3.1 算法实现3.2 测试代码3.3 运行结果 1. 算法简述 RSA为经典数字签名算法 数字签名标准(Digital Signature Standard, DSS), DSS本质是ElGamal数字签名算法,DSS使用的算法成为数字签名算法(Digital Signature Algorithm, DSA

数字签名算法之RSA

数字签名算法之RSA 1.数字签名简述2. 模型分析3. 代码实现3.1 签名算法实现3.2 测试代码3.3 运行结果 1.数字签名简述 数字签名算法可以看做是一种带有密钥的消息摘要算法,并且这种密钥包含了公钥和私钥。也就是说数字签名算法是非对称加密算法和消息摘要算法的结合体。 数字签名算法是公钥基础设施(PKI)以及许多网络安全机制(SSL/TLS、VPN等)的基础。 数

最新的kali Linux源,解决apt update报错说没有数字签名

原因: 国内源的地址大部分都是http开头,这些地址早就无法使用。 解决方案: wget archive.kali.org/archive-key.asc                 //下载签名 apt-key add archive-key.asc                               //安装签名 另外,需要kali Linux更换最新的源地址:

接口安全--http数字签名

为了保证http请求数据的安全性和防篡改性。我们通常要对请求参数进行一些加密。 加密规则可以根据双方接口协商定义。这里举一个常用的加密协议例子。 1. sign加密协议 接口协议中通常会提供一个 appKey作为唯一的标识。 appSecret作为接入密钥。 例如:appkey=hh appSecret=39ertfefdsg406c7c36592d42022aaecc 请求路径 h

数字证书及其简单数字签名的实现

<!--[if !supportLists]-->1、<!--[endif]-->引导语/数字证书的应用 提到数字证书,大家首先可能想到这些。 然而其实这些也是数字证书运用很广泛的地方,可以说,数字证书是整个信息时代网络安全及其有力的一种保障。  我们可以简单的用一种很直接的方法查看我们的证书,比如右击一个exe类型的文件,打开文件的属性,然后你可以很清楚的看到数字证书这个选项。一般合格的企业都

数字证书及其简单数字签名的实现(java实现)

<!--[if !supportLists]-->1、<!--[endif]-->引导语/数字证书的应用 提到数字证书,大家首先可能想到这些。  然而其实这些也是数字证书运用很广泛的地方,可以说,数字证书是整个信息时代网络安全及其有力的一种保障。  我们可以简单的用一种很直接的方法查看我们的证书,比如右击一个exe类型的文件,打开文件的属性,然后你可以很清楚的看到数字证书这个选项。一般合格的企

数字签名是什么? 对称加密 与非对称加密

原址:点击打开链接 (一)对称加密(Symmetric Cryptography) 对称加密是最快速、最简单的一种加密方式,加密(encryption)与解密(decryption)用的是同样的密钥(secret key),这种方法在密码学中叫做对称加密算法。对称加密有很多种算法,由于它效率很高,所以被广泛使用在很多加密协议的核心当中。 对称加密通常使用的是相对较小的密钥,一般小于256 bit

现代密码学-数字签名

从消息认证码到数字签名 前面讲到,消息认证码无法防止否认,A,B之间共享密钥计算出MAC,A,B都能计算出MAC,对于第三方C来说,他无法证明这个MAC是A计算的还是B计算的。 通过数字签名解决问题。 A,B各自使用不同的密钥-公钥密码,A用私钥生成一个签名,B可以用A公开的公钥进行验证。 签名的生成和验证 数字签名中的两种行为:         生成消息签名         验证消