From:http://hedong.3322.org/archives/000566.html
- 存储/删除密码。如果密码是存储在 Java String 对象中的,则直到对它进行垃圾收集或进程终止之前,密码会一直驻留在内存中。即使进行了垃圾收集,它仍会存在于空闲内存堆中,直到重用该内存空间为止。密码 String 在内存中驻留得越久,遭到窃听的危险性就越大。更糟的是,如果实际内存减少,则操作系统会将这个密码 String 换页调度到磁盘的交换空间,因此容易遭受磁盘块窃听攻击。为了将这种泄密的可能性降至最低(但不是消除),您应该将密码存储在 char 数组中,并在使用后对其置零。(String 是不可变的,所以无法对其置零。)
- 智能序列化。当为存储器或传输任何私有字段而序列化对象时,缺省情况下,这些对象都呈现在流中。因此,敏感数据很容易被窃听。可以使用 transient 关键字来标记属性,这样在流中将忽略该属性。
一些安全概念及在jdk1.4中的实现
- 消息摘要。这是一种与消息认证码结合使用以确保消息完整性的技术。
- 私钥加密。被设计用来确保消息机密性的技术。
- 公钥加密。允许通信双方不必事先协商秘钥即可共享秘密消息的技术。
- 数字签名。证明另一方的消息确定来自正确通信方的位模式。
- 数字证书。通过让第三方认证机构认证消息,向数字签名添加另一级别安全性的技术。
- 代码签名。由可信的实体将签名嵌入被传递的代码中的概念。
- SSL/TLS。在客户机和服务器之间建立安全通信通道的协议。传输层安全性(Transport Layer Security (TLS))是安全套接字层(Secure Sockets Layer (SSL))的替代品。
- 消息摘要。这是一种与消息认证码结合使用以确保消息完整性的技术。
- 它获取消息中的数据并生成一个被设计用来表示该消息"指纹"的位块。
- 消息摘要函数是单向函数。从消息生成指纹是很简单的事情,但生成与给定指纹匹配的消息却很难。
- 私钥加密。被设计用来确保消息机密性的技术。
- Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
- cipher.init(Cipher.ENCRYPT_MODE, key);
- byte[] cipherText = cipher.doFinal(plainText);
- 公钥加密。允许通信双方不必事先协商秘钥即可共享秘密消息的技术。
- 公钥和私钥是成对生成的,并需要比同等强度的私钥加密密钥更长。RSA 算法的典型密钥长度是 1,024 位。从该密钥对的一个成员派生出另一个是不可行的。
- 公钥加密比较慢(比私钥加密慢 100 到 1,000 倍),因此实际上通常使用混合技术。公钥加密被用于向对方分发称为会话密钥的私钥,使用该私有会话密钥的私钥加密被用于进行大量的消息加密。
- 公钥加密中使用下列两种算法:
- RSA。这个算法是最流行的公钥密码,但 JDK 1.4 中不支持它。您必须使用类似于 BouncyCastle 的第三方库来获得这种支持。
- Diffie-Hellman。技术上将这种算法称为密钥协定算法。它不能用于加密,但可以用来允许双方通过在公用通道上共享信息来派生出秘钥。然后这个密钥可以用于私钥加密。
- KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
- keyGen.initialize(1024);
- KeyPair key = keyGen.generateKeyPair();
- Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
- cipher.init(Cipher.ENCRYPT_MODE, key.getPublic());
- byte[] cipherText = cipher.doFinal(plainText);
- cipher.init(Cipher.DECRYPT_MODE, key.getPrivate());
- byte[] newPlainText = cipher.doFinal(cipherText);
- 数字签名。证明另一方的消息确定来自正确通信方的位模式。
- 发送方用私钥来对消息签名,然后接收方用发送方的公钥来解密
- 数字签名不提供消息加密
- 可以将 RSA 算法用于数字签名和加密。名为 DSA(数字签名算法 (Digital Signature Algorithm))的美国标准可以用于数字签名,但不可以用于加密。
- 数字证书。通过让第三方认证机构认证消息,向数字签名添加另一级别安全性的技术。
- 认证中心(CA)是验证某个实体的身份并用 CA 私钥对该实体的公钥和身份进行签名的组织。消息接收方可以获取发送方的数字证书并用 CA 的公钥验证(或解密)该证书。这可以证实证书是否有效,并允许接收方抽取发送方的公钥来验证其签名或向他发送加密的消息。
- 浏览器和 JDK 本身都带有内置的来自几个 CA 的证书及其公钥。
- 代码签名。由可信的实体将签名嵌入被传递的代码中的概念。
- jarsigner 工具将一个 JAR 文件、一个私钥和相应的证书作为输入,然后生成 JAR 文件的签名版本作为输出。它为 JAR 文件中的每个类计算消息摘要,然后对这些摘要进行签名以确保文件的完整性并标识文件的拥有者。
- jar cvf HelloWorld.jar HelloWorld.class
- jarsigner HelloWorld.jar JoeUserKey
- jarsigner -verify -verbose -certs HelloWorld.jar
- SSL/TLS。在客户机和服务器之间建立安全通信通道的协议。传输层安全性(Transport Layer Security (TLS))是安全套接字层(Secure Sockets Layer (SSL))的替代品。
- SSLServerSocketFacctory sslf = (SSLServerSocketFactor)SSLServerSocketFactory.getDefault();
- ServerSocket serverSocket = sslf.createServerSocket(PORT);
- 当使用 SSL/TLS(通常使用 https:// URL)向站点进行请求时,从服务器向客户机发送一个证书。客户机使用已安装的公共 CA 证书通过这个证书验证服务器的身份,然后检查 IP 名称(机器名)与客户机连接的机器是否匹配。
- 客户机生成一些可以用来生成对话的私钥(称为会话密钥)的随机信息,然后用服务器的公钥对它加密并将它发送到服务器。服务器用自己的私钥解密消息,然后用该随机信息派生出和客户机一样的私有会话密钥。通常在这个阶段使用 RSA 公钥算法。
- 然后,客户机和服务器使用私有会话密钥和私钥算法(通常是 RC4)进行通信。使用另一个密钥的消息认证码来确保消息的完整性。
参考文献:
JAVA安全性第一部分 密码学基础