设为首页 加入收藏

TOP

Java结合keytool实现非对称加密和解密(一)
2018-08-09 09:13:12 】 浏览:292
Tags:Java 结合 keytool 实现 对称 加密 解密

参考:Java结合keytool实现非对称签名与验证

那一篇讲签名,这一篇将加密解密。在Java安全体系中,签名属于JAAS模块,加解密属于JCE模块。

keytool的使用

keytool是JDK自带的一个密钥库管理工具。这里只用到了keytool的部分功能,包括生成密钥对,导出公钥等。keytool生成的公钥/私钥对存放到一个到了一个文件中,这个文件有密码保护,通称为keystore。

生成密钥对

$ keytool -genkey -alias signLegal -keystore examplestanstore2 -validity 1800 -keyalg RSA

生成别名为signLegal的密钥对,存放在密钥库examplestanstore2中,证书的有效期是1800天(默认是90天)。
输入一系列的参数。输入的参数遵循了LDAP的风格和标准。可以想象,生成的密钥对可以看成LDAP的一个条目。
命令执行成功后会在当前目录下创建一个叫examplestanstore2的文件。相对另一篇博文,增加了一个keyalg参数。因为keytool默认算法是DSA,而DSA只能用于签名。RSA既能用于签名,也能用于加密。而本文是研究加密问题,只能用RSA算法。

查看密钥对

$ keytool -list -keystore examplestanstore2 -v

列出了examplestanstore2密钥库的中所有密钥对。-v参数表示详细信息,详细信息中有证书的失效时间。

导出公钥证书

$ keytool -export -keystore examplestanstore2 -alias signLegal -file StanSmith.crt -rfc

导出的公钥存放在当前目录的StanSmith.crt文件中。讲“签名”的那篇博文没有加-rfc参数,导出是个二进制文件(CER格式)。加上-rfc后,导出的是文本文件(PEM)格式。在下面的测试中,如果使用CER格式,会报错 ` No installed provider supports this key: sun.security.provider.DSAPublicKeyImpl`。

Java加密和解密

参考了这篇文章《Java-web下使用RSA进行加密解密操作

在Java程序中,首先从密钥库取出私钥和公钥,然后对测试字符串进行加密。二进制的密文转换成字符串输出到屏幕,然后解密成明文再输出到屏幕。

GenSig2.java

import java.io.*;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.PublicKey;
import javax.crypto.Cipher;
import sun.security.provider.*;

public class RSAEntry {
    public static void main(String[] args) {
        try {
        //1.从密钥库中取私钥
        KeyStore ks = KeyStore.getInstance("JKS");
        FileInputStream ksfis = new FileInputStream("examplestanstore2");
        BufferedInputStream ksbufin = new BufferedInputStream(ksfis);

        // open keystore and get private key
        // alias is 'signLeal', kpasswd/spasswd is 'vagrant'
        ks.load(ksbufin, "vagrant".toCharArray());
        PrivateKey prikey = (PrivateKey) ks.getKey("signLegal", "vagrant".toCharArray());

        //2.根据命令行参数取公钥
        FileInputStream certfis = new FileInputStream(args[0]);
        java.security.cert.CertificateFactory cf =
            java.security.cert.CertificateFactory.getInstance("X.509");
        java.security.cert.Certificate cert =  cf.generateCertificate(certfis);
        PublicKey pubKey = cert.getPublicKey();

        //3.使用公钥进行加密
        String data = "测试数据";
        //构建加密解密类
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, pubKey);//设置为加密模式
        byte[] jmdata = cipher.doFinal(data.getBytes());
        //打印加密后数据
        System.out.println(bytesToHexString(jmdata));
        //改为解密模式进行解密
        cipher.init(Cipher.DECRYPT_MODE, prikey);//会用私钥解密
        jmdata = cipher.doFinal(jmdata);
        System.out.println(new String(jmdata));
        }catch (Exception e) {
                e.printStackTrace();
        }
    }
    //这个方法用于把二进制转换成ASCII字符串。
    public static String bytesToHexString(byte[] bytes) {
        if (bytes == null)
            return "null!";
        int len = bytes.length;
        StringBuilder ret = new StringBuilder(2 * len);

        for (int i = 0; i < len; ++i) {
            int b = 0xF & bytes[(i)] >> 4;
            ret.append("0123456789abcdef".charAt(b));
            b = 0xF & bytes[(i)];
            ret.append("0123456789abcdef".charAt(b));
        }

        return ret.toString();
    }
}

编译,并运行

$ javac RSAEntry.java
$ java RSAEntry StanSmith.crt
8fceea48e34fdc786bde05459f3366714b650ff04f4e81e52eca139d8ee0b4acbcad019cd496
首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Java连接HBase(kerberized集群) 下一篇Java 动态代理及 RPC 框架介绍

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目