了解Java密码扩展的基础

 
了解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),用以加密你网上交易的重要信息。

(责任编辑 火凤凰 [email protected]  TEL:(010)68476636-8007)

 
时间: 2024-10-14 07:15:41

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

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

下载与JDK或JRE对应版本的jce文件包,当前需要机器的jdk为1.8,所以下载jce_policy-8.zip. 下载地址: 下载解压后,把里面的jar文件上传到需要安装jce机器上的JDK或JRE的security目录下,覆盖源文件即可. JDK:将两个jar文件也放到%JDK_HOME%\jre\lib\security下 JRE:将两个jar文件放到%JRE_HOME%\lib\security下 覆盖之前,记得备份源文件,以防万一. # pwd /usr/java/java-8-or

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

因为某些国家的进口管制限制,Java发布的运行环境包中的加解密有一定的限制.比如默认不允许256位密钥的AES加解密,解决方法就是修改策略文件. 官方网站提供了JCE无限制权限策略文件的下载: JDK6的下载地址:   http://www.oracle.com/technetwork/java/javase/downloads/jce-6-download-429243.html JDK7的下载地址:   http://www.oracle.com/technetwork/java/javas

JAVA学习篇--JSTL基础

JSTL是什么 JSTL(JSP Standard TagLibrary,JSP标准标签库)是一个不断完善的开放源代码的JSP标签库. 为什么要用JSTL 我们JSP用于开发信息展现页非常方便;也可以嵌入java代码(scriptlet.表达式和声明)代码用来实现相关逻辑控制.看下面程序.但这样做会带来如下问题: jsp维护难度增加;出错提示不明确,不容易调试; 分工不明确;(即jsp开发者是美工,也是程序员); 最终增加程序的开发成本; <% if (session.getAttribute(

JAVA 面向对象的一些基础理解

方法的定义:方法就是一段可重复调用的代码段格式: 访问修饰符 返回值类型(可以是void.基本数据类型.引用数据类型) 方法名(){ 方法主体 }注意:void返回值类型不需要返回值,而其他类型都需要有返回值. 方法的重载:方法名称相同,但是参数的类型和个数不同,通过传递参数的个数和类型来完成不同功能的操作. 类和对象的关系:类是对某一事物的描述,是抽象的.概念上的意义,对象是实际存在的该类事物的每一个个体,也被称为实例类的声明格式:class 类名称{ 属性 方法 }类名 对象名=null//

[基础] Java目录(摘自Java核心技术·卷1 基础知识)

Java核心技术·卷1 基础知识(原书第9版) 第1章 Java程序设计概述 1.1 Java程序设计平台 1.2 Java"白皮书"的关键术语 1.2.1 简单性 1.2.2 面向对象 1.2.3 网络技能 1.2.4 健壮性 1.2.5 安全性 1.2.6 体系结构中立 1.2.7 可移植性 1.2.8 解释型 1.2.9 高性能 1.2.10 多线程 1.2.11 动态性 1.3 Java applet与Internet 1.4 Java发展简史 1.5 关于Java的常见误解

java面试题大全-基础方面

Java基础方面: 1.作用域public,private,protected,以及不写时的区别答:区别如下:作用域           当前类       同一package  子孙类       其他packagepublic            √              √                  √             √protected        √              √                  √             ×friendly

Java回顾之Spring基础

第一篇:Java回顾之I/O 第二篇:Java回顾之网络通信 第三篇:Java回顾之多线程 第四篇:Java回顾之多线程同步 第五篇:Java回顾之集合 第六篇:Java回顾之序列化 第七篇:Java回顾之反射 第八篇:Java回顾之一些基础概念 第九篇:Java回顾之JDBC 第十篇:Java回顾之ORM框架 我计划分两到三篇文章来描述Spring,这一篇主要讲Spring一些基础的内容. 概述 我印象4.5年前,我还做java开发的时候,Spring是一个非常火的框架,尤其是在Web开发领域

风雨java路之【基础篇】——异常的那些事儿

异常,说白了,就是不正常,就是由于种种原因产生了非正常的结果.生活中此现象比比皆是,举个简单的例子: 去ATM机取钱,插入银行卡,没反应,这就是异常,可能是机器坏了,也可能是卡消磁了等等:读卡成功,输入密码时,铵错按钮,这也是异常:密码正确,想取¥1000,结果余额不足,这又是异常:钱取完了,卡被吞了,这还是异常:-- 拿人来说,沙尘迷眼了,这是异常情况:喝水呛着了,这也是异常:水指不小心划破流血了,这也是异常:-- 出现这些情况该怎么办?那就需要"异常机制",对于ATM机,他有自己的

2018.6.19 Java模拟考试(基础习题)

Java模拟考试(基础习题) 一.单选题(每题1分 * 50 = 50分) 1.java程序的执行过程中用到一套JDK工具,其中javac.exe指( B ) A.java语言解释器 B.java字节码编译器 C.java文档生成器 D.java类分解器 2.在Java语言中,不允许使用指针体现出的Java特性是( D ) A.可移植 B.解释执行 C.健壮性 D.安全性 3. 00101010(&)00010111语句的执行结果是( C ) A.11111111 B.00111111 C.00