知识大全 Java加密技术(九)

Posted

篇首语:一卷旌收千骑虏,万全身出百重围。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 Java加密技术(九)相关的知识,希望对你有一定的参考价值。

Java加密技术(九)  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!

  在Java加密技术(八)中 我们模拟了一个基于RSA非对称加密网络的安全通信 现在我们深度了解一下现有的安全网络通信——SSL

  我们需要构建一个由CA机构签发的有效证书 这里我们使用上文中生成的自签名证书zlex cer

  这里 我们将证书导入到我们的密钥库

  Shell代码

  keytool import alias file d /zlex cer keystore d /zlex keystore

  其中

   import表示导入

   alias指定别名 这里是

   file指定算法 这里是d /zlex cer

   keystore指定存储位置 这里是d /zlex keystore

  在这里我使用的密码为

  控制台输出

  Console代码  输入keystore密码 再次输入新密码:所有者:CN= OU=zlex O=zlex L=BJ ST=BJ C=CN签发人:CN= OU=zlex O=zlex L=BJ ST=BJ C=CN序列号: a e df有效期: Thu May : : CST 至Wed Aug : : CST 证书指纹:         MD : :CA:E : :E :DF:AD: : : : F:A :AD:FC: : A         SHA : : : : : : :F : :CA: :A : D: A:CF: :D :C :D :C :C          签名算法名称:SHA withRSA         版本: 信任这个认证? [否]   y认证已添加至keystore中

  OK 最复杂的准备工作已经完成

  接下来我们将域名定位到本机上 打开C \\Windows\\System \\drivers\\etc\\hosts文件 将绑定在本机上 在文件末尾追加        现在通过地址栏访问 或者通过ping命令 如果能够定位到本机 域名映射就搞定了

  现在 配置tomcat 先将zlex keystore拷贝到tomcat的conf目录下 然后配置server xml 将如下内容加入配置文件

  Xml代码  <Connector    SSLEnabled= true     URIEncoding= UTF     clientAuth= false     keystoreFile= conf/zlex keystore     keystorePass=     maxThreads=     port=     protocol= HTTP/     scheme=     secure= true     sslProtocol= TLS />

  注意clientAuth= false 测试阶段 置为false 正式使用时建议使用true 现在启动tomcat 访问

  

  显然 证书未能通过认证 这个时候你可以选择安装证书(上文中的zlex cer文件就是证书) 作为受信任的根证书颁发机构导入 再次重启浏览器(IE 其他浏览器对于域名不支持本地方式访问) 访问 你会看到地址栏中会有个小锁 就说明安装成功 所有的浏览器联网操作已经在RSA加密解密系统的保护之下了 但似乎我们感受不到

  这个时候很多人开始怀疑 如果我们要手工做一个这样的的访问是不是需要把浏览器的这些个功能都实现呢?不需要!

  接着上篇内容 给出如下代码实现

  Java代码

  import java io FileInputStream;import java security KeyStore;import java security PrivateKey;import java security PublicKey;import java security Signature;import java security cert Certificate;import java security cert CertificateFactory;import java security cert X Certificate;import java util Date;

  import javax crypto Cipher;import ssl HttpsURLConnection;import ssl KeyManagerFactory;import ssl SSLContext;import ssl SSLSocketFactory;import ssl TrustManagerFactory;

  /** * 证书组件 * * @author 梁栋 * @version  * @since  */public abstract class CertificateCoder extends Coder

  /**     * Java密钥库(Java Key Store JKS)KEY_STORE     */    public static final String KEY_STORE = JKS ;

  public static final String X = X ;    public static final String SunX = SunX ;    public static final String SSL = SSL ;

  /**     * 由KeyStore获得私钥     *     * @param keyStorePath     * @param alias     * @param password     * @return     * @throws Exception     */    private static PrivateKey getPrivateKey(String keyStorePath String alias             String password) throws Exception         KeyStore ks = getKeyStore(keyStorePath password);        PrivateKey key = (PrivateKey) ks getKey(alias password toCharArray());        return key;   

  /**     * 由Certificate获得公钥     *     * @param certificatePath     * @return     * @throws Exception     */    private static PublicKey getPublicKey(String certificatePath)            throws Exception         Certificate certificate = getCertificate(certificatePath);        PublicKey key = certificate getPublicKey();        return key;   

  /**     * 获得Certificate     *     * @param certificatePath     * @return     * @throws Exception     */    private static Certificate getCertificate(String certificatePath)            throws Exception         CertificateFactory certificateFactory = CertificateFactory                getInstance(X );        FileInputStream in = new FileInputStream(certificatePath);

  Certificate certificate = certificateFactory generateCertificate(in);        in close();

  return certificate;   

  /**     * 获得Certificate     *     * @param keyStorePath     * @param alias     * @param password     * @return     * @throws Exception     */    private static Certificate getCertificate(String keyStorePath             String alias String password) throws Exception         KeyStore ks = getKeyStore(keyStorePath password);        Certificate certificate = ks getCertificate(alias);

  return certificate;   

  /**     * 获得KeyStore     *     * @param keyStorePath     * @param password     * @return     * @throws Exception     */    private static KeyStore getKeyStore(String keyStorePath String password)            throws Exception         FileInputStream is = new FileInputStream(keyStorePath);        KeyStore ks = KeyStore getInstance(KEY_STORE);        ks load(is password toCharArray());        is close();        return ks;   

  /**     * 私钥加密     *     * @param data     * @param keyStorePath     * @param alias     * @param password     * @return     * @throws Exception     */    public static byte[] encryptByPrivateKey(byte[] data String keyStorePath             String alias String password) throws Exception         // 取得私钥        PrivateKey privateKey = getPrivateKey(keyStorePath alias password);

  // 对数据加密        Cipher cipher = Cipher getInstance(privateKey getAlgorithm());        cipher init(Cipher ENCRYPT_MODE privateKey);

  return cipher doFinal(data);

  

  /**     * 私钥解密     *     * @param data     * @param keyStorePath     * @param alias     * @param password     * @return     * @throws Exception     */    public static byte[] decryptByPrivateKey(byte[] data String keyStorePath             String alias String password) throws Exception         // 取得私钥        PrivateKey privateKey = getPrivateKey(keyStorePath alias password);

  // 对数据加密        Cipher cipher = Cipher getInstance(privateKey getAlgorithm());        cipher init(Cipher DECRYPT_MODE privateKey);

  return cipher doFinal(data);

  

  /**     * 公钥加密     *     * @param data     * @param certificatePath     * @return     * @throws Exception     */    public static byte[] encryptByPublicKey(byte[] data String certificatePath)            throws Exception

  // 取得公钥        PublicKey publicKey = getPublicKey(certificatePath);        // 对数据加密        Cipher cipher = Cipher getInstance(publicKey getAlgorithm());        cipher init(Cipher ENCRYPT_MODE publicKey);

  return cipher doFinal(data);

  

  /**     * 公钥解密     *     * @param data     * @param certificatePath     * @return     * @throws Exception     */    public static byte[] decryptByPublicKey(byte[] data String certificatePath)            throws Exception         // 取得公钥        PublicKey publicKey = getPublicKey(certificatePath);

  // 对数据加密        Cipher cipher = Cipher getInstance(publicKey getAlgorithm());        cipher init(Cipher DECRYPT_MODE publicKey);

  return cipher doFinal(data);

  

  /**     * 验证Certificate     *     * @param certificatePath     * @return     */    public static boolean verifyCertificate(String certificatePath)         return verifyCertificate(new Date() certificatePath);   

  /**     * 验证Certificate是否过期或无效     *     * @param date     * @param certificatePath     * @return     */    public static boolean verifyCertificate(Date date String certificatePath)         boolean status = true;        try             // 取得证书            Certificate certificate = getCertificate(certificatePath);            // 验证证书是否过期或无效            status = verifyCertificate(date certificate);        catch (Exception e)             status = false;                return status;   

  /**     * 验证证书是否过期或无效     *     * @param date     * @param certificate     * @return     */    private static boolean verifyCertificate(Date date Certificate certificate)         boolean status = true;        try             X Certificate x Certificate = (X Certificate) certificate;            x Certificate checkValidity(date);        catch (Exception e)             status = false;                return status;   

  /**     * 签名     *     * @param keyStorePath     * @param alias     * @param password     *     * @return     * @throws Exception     */    public static String sign(byte[] sign String keyStorePath String alias             String password) throws Exception         // 获得证书        X Certificate x Certificate = (X Certificate) getCertificate(                keyStorePath alias password);        // 获取私钥        KeyStore ks = getKeyStore(keyStorePath password);        // 取得私钥        PrivateKey privateKey = (PrivateKey) ks getKey(alias password                toCharArray());

  // 构建签名        Signature signature = Signature getInstance(x Certificate                getSigAlgName());        signature initSign(privateKey);        signature update(sign);        return encryptBASE (signature sign());   

  /**     * 验证签名     *     * @param data     * @param sign     * @param certificatePath     * @return     * @throws Exception     */    public static boolean verify(byte[] data String sign             String certificatePath) throws Exception         // 获得证书        X Certificate x Certificate = (X Certificate) getCertificate(certificatePath);        // 获得公钥        PublicKey publicKey = x Certificate getPublicKey();        // 构建签名        Signature signature = Signature getInstance(x Certificate                getSigAlgName());        signature initVerify(publicKey);        signature update(data);

  return signature verify(decryptBASE (sign));

  

  /**     * 验证Certificate     *     * @param keyStorePath     * @param alias     * @param password     * @return     */    public static boolean verifyCertificate(Date date String keyStorePath             String alias String password)         boolean status = true;        try             Certificate certificate = getCertificate(keyStorePath alias                     password);            status = verifyCertificate(date certificate);        catch (Exception e)             status = false;                return status;   

  /**     * 验证Certificate     *     * @param keyStorePath     * @param alias     * @param password     * @return     */    public static boolean verifyCertificate(String keyStorePath String alias             String password)         return verifyCertificate(new Date() keyStorePath alias password);   

  /**     * 获得SSLSocektFactory     *     * @param password     *            密码     * @param keyStorePath     *            密钥库路径     *     * @param trustKeyStorePath     *            信任库路径     * @return     * @throws Exception     */    private static SSLSocketFactory getSSLSocketFactory(String password             String keyStorePath String trustKeyStorePath) throws Exception         // 初始化密钥库        KeyManagerFactory keyManagerFactory = KeyManagerFactory                getInstance(SunX );        KeyStore keyStore = getKeyStore(keyStorePath password);        keyManagerFactory init(keyStore password toCharArray());

  // 初始化信任库        TrustManagerFactory trustManagerFactory = TrustManagerFactory                getInstance(SunX );        KeyStore trustkeyStore = getKeyStore(trustKeyStorePath password);        trustManagerFactory init(trustkeyStore);

  // 初始化SSL上下文        SSLContext ctx = SSLContext getInstance(SSL);        ctx init(keyManagerFactory getKeyManagers() trustManagerFactory                getTrustManagers() null);        SSLSocketFactory sf = ctx getSocketFactory();

  return sf;   

  /**     * 为HttpsURLConnection配置SSLSocketFactory     *     * @param conn     *            HttpsURLConnection     * @param password     *            密码     * @param keyStorePath     *            密钥库路径     *     * @param trustKeyStorePath     *            信任库路径     * @throws Exception     */    public static void configSSLSocketFactory(HttpsURLConnection conn             String password String keyStorePath String trustKeyStorePath)            throws Exception         conn setSSLSocketFactory(getSSLSocketFactory(password keyStorePath                 trustKeyStorePath));   

  增加了configSSLSocketFactory方法供外界调用 该方法为HttpsURLConnection配置了SSLSocketFactory 当HttpsURLConnection配置了SSLSocketFactory后 我们就可以通过HttpsURLConnection的getInputStream getOutputStream 像往常使用HttpURLConnection做操作了 尤其要说明一点 未配置SSLSocketFactory前 HttpsURLConnection的getContentLength()获得值永远都是

  给出相应测试类

  Java代码

  import static junit Assert *;

  import java io DataInputStream;import java io InputStream;import URL;

  import ssl HttpsURLConnection;

  import junit Test;

  /** * * @author 梁栋 * @version  * @since  */public class CertificateCoderTest     private String password = ;    private String alias = ;    private String certificatePath = d:/zlex cer ;    private String keyStorePath = d:/zlex keystore ;    private String clientKeyStorePath = d:/zlex client keystore ;    private String clientPassword = ;

  @Test    public void test() throws Exception         System err println( 公钥加密——私钥解密 );        String inputStr = Ceritifcate ;        byte[] data = inputStr getBytes();

  byte[] encrypt = CertificateCoder encryptByPublicKey(data                 certificatePath);

  byte[] decrypt = CertificateCoder decryptByPrivateKey(encrypt                 keyStorePath alias password);        String outputStr = new String(decrypt);

  System err println( 加密前: + inputStr + \\n\\r + 解密后: + outputStr);

  // 验证数据一致        assertArrayEquals(data decrypt);

  // 验证证书有效        assertTrue(CertificateCoder verifyCertificate(certificatePath));

  

  @Test    public void testSign() throws Exception         System err println( 私钥加密——公钥解密 );

  String inputStr = sign ;        byte[] data = inputStr getBytes();

  byte[] encodedData = CertificateCoder encryptByPrivateKey(data                 keyStorePath alias password);

  byte[] decodedData = CertificateCoder decryptByPublicKey(encodedData                 certificatePath);

  String outputStr = new String(decodedData);        System err println( 加密前: + inputStr + \\n\\r + 解密后: + outputStr);        assertEquals(inputStr outputStr);

  System err println( 私钥签名——公钥验证签名 );        // 产生签名        String sign = CertificateCoder sign(encodedData keyStorePath alias                 password);        System err println( 签名:\\r + sign);

  // 验证签名        boolean status = CertificateCoder verify(encodedData sign                 certificatePath);        System err println( 状态:\\r + status);        assertTrue(status);

  

  @Test    public void testHttps() throws Exception         URL url = new URL( );        HttpsURLConnection conn = (HttpsURLConnection) url openConnection();

  conn setDoInput(true);        conn setDoOutput(true);

  nfigSSLSocketFactory(conn clientPassword                 clientKeyStorePath clientKeyStorePath);

  InputStream is = conn getInputStream();

  int length = conn getContentLength();

  DataInputStream dis = new DataInputStream(is);        byte[] data = new byte[length];        dis readFully(data);

  dis close();        System err println(new String(data));        conn disconnect();   

  注意testHttps方法 几乎和我们往常做HTTP访问没有差别 我们来看控制台输出

  Console代码

  <!   Licensed to the Apache Sofare Foundation (ASF) under one or more  contributor license agreements   See the NOTICE file distributed with  this work for additional information regarding copyright ownership   The ASF licenses this file to You under the Apache License Version   (the License ); you may not use this file except in pliance with  the License   You may obtain a copy of the License at

  

  Unless required by applicable law or agreed to in writing sofare  distributed under the License is distributed on an AS IS BASIS   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND either express or implied   See the License for the specific language governing permissions and  limitations under the License ><!DOCTYPE HTML PUBLIC //W C//DTD HTML Transitional//EN ><HTML><HEAD><TITLE>Apache Tomcat Examples</TITLE><META equiv=Content Type content= text/ ></HEAD><BODY><P><H >Apache Tomcat Examples</H ><P></P><ul><li><a >Servlets examples</a></li><li><a >JSP Examples</a></li></ul></BODY></HTML>

    通过浏览器直接访问你也会获得上述内容 也就是说应用甲方作为服务器构建tomcat服务 乙方可以通过上述方式访问甲方受保护的SSL应用 并且不需要考虑具体的加密解密问题 甲乙双方可以经过相应配置 通过双方的tomcat配置有效的SSL服务 简化上述代码实现 完全通过证书配置完成SSL双向认证! cha138/Article/program/Java/gj/201311/27353

相关参考

知识大全 漫谈Java加密技术(一)

漫谈Java加密技术(一)  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  加密解密曾经是我一个毕

知识大全 谈谈Java加密技术(七)

谈谈Java加密技术(七)  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  ECC  ECCEll

知识大全 谈谈Java加密技术(六)

谈谈Java加密技术(六)  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  接下来我们介绍DSA数

知识大全 Java技术进阶 基于Java的IDEA加密算法探讨

Java技术进阶基于Java的IDEA加密算法探讨  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 

知识大全 漫谈Java加密技术系列文章 一至十

漫谈Java加密技术系列文章一至十  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  漫谈Java加

知识大全 深入讨论JAVA字节码加密技术(2)

深入讨论JAVA字节码加密技术(2)  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  这个累加载器

知识大全 深入讨论JAVA字节码加密技术(1)

深入讨论JAVA字节码加密技术(1)  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  如果把的cl

知识大全 论Java加密技术与Windows的结合

论Java加密技术与Windows的结合  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  论Jav

知识大全 Java文件加密-spring属性文件加密

Java文件加密-spring属性文件加密  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  pac

知识大全 java中使用MD5加密算法进行加密

java中使用MD5加密算法进行加密  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  在各种应用系