了解Java密码扩展的基础
 
 

Java密码扩展(The Java Cryptography Extension),是JDK1.4的一个重要部分,基本上,他是由一些包构成的,这些包形成了一个框架并实现了一些加密,密钥生成算法和协议,消息认证码等算法,这篇文章将想你介绍JCE的安装和使用。
    
值得注意的是,尽管JCE是JDK1.4的核心包的一部分,我们将首先用JDK1.2及高一点的版本向你演示一下如何安装配置JCE(静态安装)。稍后,将向你介绍如何在不安装的情况下使用JCE(动态安装)。最后,将演示怎么生成密钥和密码,及如果进行基本的加密、解密。

提供者是什么?
    
提供者是特定加密算法的实现者,有的提供者(提供的加密技术)是免费的,有的不免费,IBM, Bouncy Castle, 和 RSA都是一些(加密)提供者.在本文的后面,我们将考察一下来自Bouncy Castle的RSA算法。Sun 也向大家说明了如果实现自己的提供者(需要符合jDK的一些约定)。

静态安装
    
在安装和使用JCE之前,你需要从 Sun Web site(这里是以暗中sun的提供者为例)。获得他的安装包,JCE有sun他自己的安全提供者-sunJCE,为了吧sunJCE静态的安装到默认的提供者列表中,你需要修改安全属性文件:

◆<java-home>\jre\lib\security\java.security (Win32) 
◆<java-home>/jre/lib/security/java.security (UNIX)

如果你把JDK安装在C:\jdk1.3,你需要编辑以下文件:
C:\jdk1.3\jre\lib\security\java.security

为了安装SunJCE,你需要在以上文件中加入:
security.provider.n=com.sun.crypto.provider.SunJCE

把n用你加入的提供者的优先级代替(注意:序号要保持递增,不能跳过,但可以调整前后顺序)。

Listing A 用于查看你安装过的提供者的信息,结果在Listing B中列出,显示提供者的能力,比如说可用的加密算法。

Listing A:ProviderInformation.java

import java.security.Provider;
import java.security.Security;
import java.util.Set;
import java.util.Iterator;
public class ProviderInformation {
    public static void main(String[] args) {
        Provider[] providers = Security.getProviders();
        for (int i = 0; i < providers.length; i++) {
            Provider provider = providers[i];
            System.out.println("Provider name: " + provider.getName());
           System.out.println("Provider information: " + provider.getInfo());
            System.out.println("Provider version: " + provider.getVersion());
            Set entries = provider.entrySet();
            Iterator iterator = entries.iterator();
           while (iterator.hasNext()) {
                System.out.println("Property entry: " + iterator.next());
            }
        }
    }
}

Listing B:ProviderInformation.java output

Provider name: SUN
Provider information: SUN (DSA key/parameter generation; DSA signing; SHA-1, MD5 digests;

SecureRandom; X.509 certificates; JKS keystore)
Provider version: 1.2
Property entry: Alg.Alias.KeyFactory.1.2.840.10040.4.1=DSA
Property entry: Alg.Alias.Signature.1.2.840.10040.4.3=SHA1withDSA
Property entry: Alg.Alias.KeyPairGenerator.OID.1.2.840.10040.4.1=DSA
Property entry: Signature.SHA1withDSA KeySize=1024
Property entry: Signature.SHA1withDSA ImplementedIn=Software

动态安装:Listing c 说明了如何在运行时动态加载安全提供者,要注意的是,当你用Security.addProvider(…)加载提供者时,它是对整个JVM环境都有用的;

Listing C:DynamicProvider.java

import java.security.Security;
public class DynamicProvider {
    public static void main(String[] args) {
        // This is all there is to it!
        Security.addProvider(new com.sun.crypto.provider.SunJCE());
    }
}

如前所述,当你安装一个提供者时,你用n来指明此提供者的优先级,但一个算法的实例被调用时,JVM将按照提供的优先级来在已经安装的提供者中查找可用的实现,并使用他首先找到的可用算法。你也可用在调研时加上附加参数来指明要在那个提供者中寻找使用的算法。

实现细节:
JCE API包含了大量的为实现安全特性的类和接口,首先,我们做一个DES对称加密的例子。

生成密钥:
Listing D 展示了如果初时化密钥生成器来生成密钥;

Listing D:DESKeyGenerator.java

import javax.crypto.KeyGenerator;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.Security;
public class DESKeyGenerator {
    public static void main(String[] args) {
        Security.addProvider(new com.sun.crypto.provider.SunJCE());
        try {
            KeyGenerator kg = KeyGenerator.getInstance("DES");
            Key key = kg.generateKey();
            System.out.println("Key format: " + key.getFormat());
            System.out.println("Key algorithm: " + key.getAlgorithm());
        }
        catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
    }
}

#p#

为了生成密钥,我们首先要初始化密钥生成器,这一步可以通过调用KeyGenerator类的静态方法getInstance来实现。我们所用的vanilla DES算法没有模式和填充模型。你同样可以(在getInstance(""))传入DES/ECB/PKCS5Padding来指明模式(ECB)和填充模式(PKCS5Padding);也可以传入另外一个参数指明所用的提供者,不过这是可选的;

KeyGenerator kg = KeyGenerator.getInstance("DES");

一旦我们有了特定的密钥生成对象,我们就可以用他得到密钥:

Key key = kg.generateKey();

生成密码:

生成密码的过程跟生成密钥类似,需要调用Cipher类的getInstance方法,参数要跟生成密钥时用的参数保持一致;

Cipher cipher = Cipher.getInstance(“DES”);

Listing E 说明了如果操作:
Listing E: DESCipherGenerator.java

import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import java.security.Security;
import java.security.NoSuchAlgorithmException;
public class DESCipherGenerator {
    public static void main(String[] args) {
        Security.addProvider(new com.sun.crypto.provider.SunJCE());
        try {
            Cipher cipher = Cipher.getInstance("DES");
            System.out.println("Cipher provider: " + cipher.getProvider());
            System.out.println("Cipher algorithm: " + cipher.getAlgorithm());
        }
        catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        catch (NoSuchPaddingException e) {
            e.printStackTrace();
        }
    }
}

加解密数据
    
加密是对字节的,所以保密行比较高,当你准备好了密钥和密码时,你已经做好了加密的准备,要注意的时,同一个算法要用相同的密钥和密码,比如说,你不能用DESsede的密钥,用DES的密码,密码对象用同一个方法对数据进行加密和解密,所有你要首先初时化,让他知道你要干什么:

cipher.init(Cipher.ENCRYPT_MODE, key);

这就将初始化Cipher类,以准备好加密数据,.最简单的加密方法及时对传入的字节数组调用doFinal方法:

byte[] data = “Hello World!”.getBytes();
byte[] result = cipher.doFinal(data);

Listing F 是详细的代码

Listing F: DESCryptoTest.java

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.BadPaddingException;
import java.security.Key;
import java.security.Security;
import java.security.NoSuchAlgorithmException;
import java.security.InvalidKeyException;
public class DESCryptoTest {
    public static void main(String[] args) {
        Security.addProvider(new com.sun.crypto.provider.SunJCE());
        try {
            KeyGenerator kg = KeyGenerator.getInstance("DES");
            Key key = kg.generateKey();
            Cipher cipher = Cipher.getInstance("DES");
 
            byte[] data = "Hello World!".getBytes();
            System.out.println("Original data : " + new String(data));
 
            cipher.init(Cipher.ENCRYPT_MODE, key);
            byte[] result = cipher.doFinal(data);
            System.out.println("Encrypted data: " + new String(result));
 
            cipher.init(Cipher.DECRYPT_MODE, key);
            byte[] original = cipher.doFinal(result);
            System.out.println("Decrypted data: " + new String(original));
        }
        catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        catch (NoSuchPaddingException e) {
            e.printStackTrace();
        }
        catch (InvalidKeyException e) {
            e.printStackTrace();
        }
        catch (IllegalStateException e) {
            e.printStackTrace();
        }
        catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        }
        catch (BadPaddingException e) {
            e.printStackTrace();
        }
    }
}

总结:JCE是个功能强大的API,提供了众多的加密方法和其他安全相关的属性,我们已经找到怎样动态和静态安装JCE,并用DES对一段简单的信息进行了加密和解密,在本系列的第二部分,我们将把本文的知识用到现实的应用中去,将告诉大家如果写一个跟Socket配合使用的包装类(Wrapper),用以加密你网上交易的重要信息。

(责任编辑 火凤凰 sunsj@51cto.com  TEL:(010)68476636-8007)

 

了解Java密码扩展的基础的更多相关文章

  1. Java 密码扩展无限制权限策略文件

    因为某些国家的进口管制限制,Java发布的运行环境包中的加解密有一定的限制.比如默认不允许256位密钥的AES加解密,解决方法就是修改策略文件.   官方网站提供了JCE无限制权限策略文件的下载:   ...

  2. jce_policy安装【java密码扩展无限制权限策略文件安装】

    下载与JDK或JRE对应版本的jce文件包,当前机器的jdk为1.8,所以下载jce_policy-8.zip. 下载地址:http://www.oracle.com/technetwork/java ...

  3. Java 密码扩展无限制权限策略文件[转]

    因为某些国家的进口管制限制,Java发布的运行环境包中的加解密有一定的限制.比如默认不允许256位密钥的AES加解密,解决方法就是修改策略文件. 官方网站提供了JCE无限制权限策略文件的下载: JDK ...

  4. Java 教程整理:基础、项目全都有

    Java 在编程语言排行榜中一直位列前排,可知 Java 语言的受欢迎程度了. 网上有很多 Java 教程,无论是基础入门还是开发小项目的教程都比比皆是,可是系统的很少,对于Java 学习者来说找到系 ...

  5. Java回顾之Spring基础

    第一篇:Java回顾之I/O 第二篇:Java回顾之网络通信 第三篇:Java回顾之多线程 第四篇:Java回顾之多线程同步 第五篇:Java回顾之集合 第六篇:Java回顾之序列化 第七篇:Java ...

  6. Java面试题之基础篇概览

    Java面试题之基础篇概览 1.一个“.java”源文件中是否可以包含多个类(不是内部类)?有什么限制? 可以有多个类,但只能有一个public的类,且public的类名必须与文件名相一致. 2.Ja ...

  7. 第87节:Java中的Bootstrap基础与SQL入门

    第87节:Java中的Bootstrap基础与SQL入门 前言复习 什么是JQ? : write less do more 写更少的代码,做更多的事 找出所有兄弟: $("div" ...

  8. Java管理扩展指南之JMX技术总览

    JMX(Java管理扩展)系列 JMX(Java管理扩展)系列旨在介绍包含于Java基础版本(Java SE)中的JMX技术.本系列提供了如何使用JMX重要技术特性的诸多示例. 一.JMX技术总览简要 ...

  9. 第90节:Java中的Linux基础

    第90节:Java中的Linux基础 linux是装载虚拟机上面的: JDK依赖包: yum install glibc.i686 MYSQL依赖包: yum -y install libaio.so ...

随机推荐

  1. Expression Blend实例中文教程(8) - 动画设计快速入门StoryBoard http://silverlightchina.net/html/tips/2010/0329/934.html

    Expression Blend实例中文教程(8) - 动画设计快速入门StoryBoard 时间:2010-03-29 11:13来源:SilverlightChina.Net 作者:jv9 点击: ...

  2. linux下的git安装及配置

    一.yum安装方式 1.安装 $ yum install curl-devel expat-devel gettext-devel openssl-devel zlib-devel $ yum -y ...

  3. java日期和时间戳格式互转

    // 将日期格式转换成时间戳 public static void main(String[] args) throws Exception{ String time = "2018-05- ...

  4. Maven的-pl -am -amd参数学习

    昨天maven的deploy任务需要只选择单个模块并且把它依赖的模块一起打包,第一时间便想到了-pl参数,然后就开始处理,但是因为之前只看了一下命令的介绍,竟然花了近半小时才完全跑通,故记录此文. 假 ...

  5. VScode相关

    这就是我想要的 VSCode 插件! VS Code 快捷键(中英文对照版) visual studio code 配置vue开发环境 vscode 这样的注释怎么生成? 能让你开发效率翻倍的 VSC ...

  6. bzoj 2016: [Usaco2010]Chocolate Eating【二分+贪心】

    二分答案,贪心判断,洛谷上要开long long #include<iostream> #include<cstdio> using namespace std; const ...

  7. 洛谷 P4016 负载平衡问题 【最小费用最大流】

    求出平均数sum,对于大于sum的点连接(s,i,a[i]-sum,0),表示这个点可以流出多余的部分,对于小于sum的点连接(i,t,sum-a[i],0)表示这个点可以接受少的部分,然后每个点向相 ...

  8. 原生js一行代码实现简易轮播图

    这是一个简易的js无限循环轮播图,只用了一行js代码就实现了无限循环,记录一下三目运算符的伟大! <!DOCTYPE html><html lang="en"&g ...

  9. 【爬坑系列】之解读kubernetes的认证原理&实践

    对于访问kube-apiserver模块的请求来说,如果是使用http协议,则会顺利进入模块内部得到自己想要的:但是如果是用的是https,则能否进入模块内部获得想要的资源,他会首先要进行https自 ...

  10. maven项目管理1

    1.maven的目录结构 src -main -java -package -test -java -package resources 2.maven命令 mvn -v :查看maven版本命令 c ...