售前咨询
技术支持
渠道合作

Java代码签名——JAVA代码安全的首选策略

基本原理:

数字签名使用密钥对(公开密钥和私有密钥),任何持有公开密钥的人都能解密、而只有加密密钥持有者(私有密钥)能够生成消息。

使用举例:

  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算法。

如果要使用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();

-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

最后,对文件进行解密,并且检验解密后的文件是否与明文相匹配。

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平台的一个独一无二且越来越重要的方面。

 

上一篇:

下一篇:

相关新闻