Java加解密的基础

2023-10-27

在Java的安全包中,包括了三部分内容:

1、JCA/JCE(Java Cryptography Architecture & JavaCryptography Extensions)
2、JSSE( Java Secure-Sockets Extension)
3、JAAS( Java Authentication & AuhorizationService)

在这里,将仅介绍加解密的实现。

Java 中的加解密的实现,是由JCA(Java Cryptography Architecture) 和JCE(Java Cryptography Extension)共同组成。 在JDK1.4之前,相关的包需要单独下载和安装。现在,Java加密扩展(JCE)已经成为Java SDK 1.4的核心组成部分。JCE是一组提供了加密框架并实现了一些加密,密钥生成算法和协议,消息认证码(MAC)等算法的Java包。

什么是Provider?
  JCA/JCE并不执行各种算法,它们只是连接应用和实际算法实现程序的一组接口。软件开发商根据JCE接口,将各种算法实现后,打包成一个Provider,可以动态地加到Java运行环境中。由于美国出口控制规定,JCA是可出口的(JCA和一个Sun的默认实现包括在Java2中),但是JCE对部分国家是限制出口的。因此,要实现一个完整的安全结构,就需要一个或多个第三方厂商提供的JCE产品,称为安全提供者(Provider)。
Provider是特定加密算法的实现者,有的供应商提供的加密技术是免费的,有的不免费。这些厂商有IBM,Bouncy Castle和RSA。Sun也给出了实现自己的Provider时需要遵循一些约定。

  在低版本JDK上JCE的安装
1.静态安装

    在安装和使用JCE之前,你需要从 Sun Web site(这里是以暗中sun的提供者为例)获得安装包。JCE中已经办函Sun自己的安全Provider - SunJCE,为了把SunJCE静态的安装到默认的Provider列表中,你需要修改安全属性文件:
•    <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用你加入的提供者的优先级代替(注意:序号要保持递增,不能跳过,但可以调整前后顺序)。
代码A,用于查看你安装过的提供者的信息,结果在显示清单B中列出,显示Provider的能力,比如说可用的加密算法。
代码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());
            }
        }
    }
}
显示清单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

动态安装:
代码C说明了如何在运行时动态加载Provider,要注意的是,当你用Security.addProvider(…)加载Provider时,它是对整个JVM环境都可用的。
代码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());
    }
}
    如前所述,当你安装一个Provider时,你用n来指明此提供者的优先级,但一个算法的实例被调用时,JVM将按照提供的优先级来在已经安装的提供者中查找可用的实现,并使用他首先找到的可用算法。你也可用在调用时加上附加参数来指明要在哪个提供者中寻找使用的算法。

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

生成密钥:
下面的代码展示了如何使用密钥生成器来生成密钥。
代码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();
        }
    }
}
为了生成密钥,首先要初始化密钥生成器,这一步可以通过调用KeyGenerator类的静态方法getInstance来实现。所用的DES算法没有模式和填充模型。你同样可以(在getInstance(""))传入DES/ECB/PKCS5Padding来指明模式(ECB)和填充模式(PKCS5Padding),也可以传入另外一个参数指明所用的Provider,不过这是可选的。在获得密钥生成器的实例后,通过调用其generateKey()方法,我们就可以获得一个密钥。
 
生成密码(Cipher):
生成Cipher的过程跟生成密钥类似,需要调用Cipher类的getInstance方法,参数要跟生成密钥时用的参数保持一致。
代码E说明了如果操作。
代码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();
        }
    }
}
 
加解密数据
加密是对字节的,所以保密行比较高,当你准备好了密钥和Cipher时,你已经做好了加密的准备。要注意的是,同一个算法要用相同的密钥和密码(Cipher)。比如说,你不能用DESsede的密钥,用DES的密码。Cipher对象用同一个方法对数据进行加密和解密,所有你要首先初时化,让他知道你要干什么:
 
cipher.init(Cipher.ENCRYPT_MODE, key);
 
这就将初始化Cipher类,以准备好去加密数据。最简单的加密方法就是对传入的字节数组调用doFinal方法:
byte[] data = “Hello World!”.getBytes();
byte[] result = cipher.doFinal(data);
 
以下是详细的代码
代码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对一段简单的信息进行了加密和解密。以上内容仅对对称( Symmetric)加密举例介绍,对于非对称及其他数字签名等,可参照Java的文档。 
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java加解密的基础 的相关文章

  • 在 Java 中连接和使用 Cassandra

    我已经阅读了一些关于 Cassandra 是什么以及它可以做什么的教程 但我的问题是如何在 Java 中与 Cassandra 交互 教程会很好 如果可能的话 有人可以告诉我是否应该使用 Thrift 还是 Hector 哪一个更好以及为什
  • 在 java 类和 android 活动之间传输时音频不清晰

    我有一个android活动 它连接到一个java类并以套接字的形式向它发送数据包 该类接收声音数据包并将它们扔到 PC 扬声器 该代码运行良好 但在 PC 扬声器中播放声音时会出现持续的抖动 中断 安卓活动 public class Sen
  • 如何找到给定字符串的最长重复子串

    我是java新手 我被分配寻找字符串的最长子字符串 我在网上研究 似乎解决这个问题的好方法是实现后缀树 请告诉我如何做到这一点或者您是否有任何其他解决方案 请记住 这应该是在 Java 知识水平较低的情况下完成的 提前致谢 附 测试仪字符串
  • Final字段的线程安全

    假设我有一个 JavaBeanUser这是从另一个线程更新的 如下所示 public class A private final User user public A User user this user user public void
  • 多个 Maven 配置文件激活多个 Spring 配置文件

    我想在 Maven 中构建一个环境 在其中我想根据哪些 Maven 配置文件处于活动状态来累积激活多个 spring 配置文件 目前我的 pom xml 的相关部分如下所示
  • 加速代码 - 3D 数组

    我正在尝试提高我编写的一些代码的速度 我想知道从 3d 整数数组访问数据的效率如何 我有一个数组 int cube new int 10 10 10 我用价值观填充其中 然后我访问这些值数千次 我想知道 由于理论上所有 3d 数组都存储在内
  • 控制Android的前置LED灯

    我试图在用户按下某个按钮时在前面的 LED 上实现 1 秒红色闪烁 但我很难找到有关如何访问和使用前置 LED 的文档 教程甚至代码示例 我的意思是位于 自拍 相机和触摸屏附近的 LED 我已经看到了使用手电筒和相机类 已弃用 的示例 但我
  • Spring Data JPA 应用排序、分页以及 where 子句

    我目前正在使用 Spring JPA 并利用此处所述的排序和分页 如何通过Spring data JPA通过排序和可分页查询数据 https stackoverflow com questions 10527124 how to query
  • 无法解析插件 Java Spring

    我正在使用 IntelliJ IDEA 并且我尝试通过 maven 安装依赖项 但它给了我这些错误 Cannot resolve plugin org apache maven plugins maven clean plugin 3 0
  • 如何在PreferenceActivity中添加工具栏

    我已经使用首选项创建了应用程序设置 但我注意到 我的 PreferenceActivity 中没有工具栏 如何将工具栏添加到我的 PreferenceActivity 中 My code 我的 pref xml
  • Java TestNG 与跨多个测试的数据驱动测试

    我正在电子商务平台中测试一系列商店 每个商店都有一系列属性 我正在考虑对其进行自动化测试 是否有可能有一个数据提供者在整个测试套件中提供数据 而不仅仅是 TestNG 中的测试 我尝试不使用 testNG xml 文件作为机制 因为这些属性
  • Eclipse Java 远程调试器通过 VPN 速度极慢

    我有时被迫离开办公室工作 这意味着我需要通过 VPN 进入我的实验室 我注意到在这种情况下使用 Eclipse 进行远程调试速度非常慢 速度慢到调试器需要 5 7 分钟才能连接到远程 jvm 连接后 每次单步执行断点 行可能需要 20 30
  • 仅将 char[] 的一部分复制到 String 中

    我有一个数组 char ch 我的问题如下 如何将 ch 2 到 ch 7 的值合并到字符串中 我想在不循环 char 数组的情况下实现这一点 有什么建议么 感谢您花时间回答我的问题 Use new String value offset
  • Java执行器服务线程池[关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 如果我使用 Executor 框架在
  • Android 中麦克风的后台访问

    是否可以通过 Android 手机上的后台应用程序 服务 持续监控麦克风 我想做的一些想法 不断聆听背景中的声音信号 收到 有趣的 音频信号后 执行一些网络操作 如果前台应用程序需要的话 后台应用程序必须能够智能地放弃对麦克风的访问 除非可
  • 如何从泛型类调用静态方法?

    我有一个包含静态创建方法的类 public class TestClass public static
  • 编译器抱怨“缺少返回语句”,即使不可能达到缺少返回语句的条件

    在下面的方法中 编译器抱怨缺少退货声明即使该方法只有一条路径 并且它包含一个return陈述 抑制错误需要另一个return陈述 public int foo if true return 5 鉴于Java编译器可以识别无限循环 https
  • 在 Maven 依赖项中指定 jar 和 test-jar 类型

    我有一个名为 commons 的项目 其中包含运行时和测试的常见内容 在主项目中 我添加了公共资源的依赖项
  • Firebase 添加新节点

    如何将这些节点放入用户节点中 并创建另一个节点来存储帖子 我的数据库参考 databaseReference child user getUid setValue userInformations 您需要使用以下代码 databaseRef
  • 节拍匹配算法

    我最近开始尝试创建一个移动应用程序 iOS Android 它将自动击败比赛 http en wikipedia org wiki Beatmatching http en wikipedia org wiki Beatmatching 两

随机推荐

  • Linux下安装openldap

    Linux下安装openldap 1 安装Berkeley DB 4 7 25 伯克利大学嵌入式数据库方案 openldap用它作为存储方案 root instance 0pk09gjj ldap wget http download or
  • DAC芯片CBM128S085

    一 硬件介绍 1 1 芯片内部框架图 1 2 CBM12S085引脚定义 引脚介绍 DAC SYNC 电平触发控制输入 低电平有效 SCLK 时钟输入 DAC DIN 串行数据输入 VOUTA H则是对应的8个电压模拟输出通道 二 软件实现
  • 找出数组中每个数的右边第一个比它大的数

    vector
  • 人工智能 猴子摘香蕉问题

    1 定义描述环境状态的谓词 AT x w x在w处 个体域 x monkey w a b c box HOLD x t x手中拿着t 个体域 t box banana EMPTY x x手中是空的 ON t y t在y处 个体域 y b c
  • 三角形

    1 2 3 4 5 6
  • function 与 => 的区别

    function 与 的区别主要是他们的作用域的不同 在JS中 箭头函数并不是简单的function 匿名函数的简写语法糖 实际上 箭头函数和匿名函数有个明显的区别 gt 箭头函数内部的this是词法作用域 在编写函数时就已经确定了 fun
  • CentOS8.4安装Redis6.2.6

    一 下载 官网 Redis 我们下载 Stable 稳定版 cd mydata wget https download redis io releases redis 6 2 6 tar gz 二 安装redis6 2 6 1 安装到 us
  • python编一函数s(x) 求级数和_Python 编程基础之高阶函数篇(一)

    高阶函数 能接受函数作为参数的函数 如 f abs def add x y f return f x f y 如果我们用 add 5 9 f 来调用该高阶函数 则返回结果为 14 abs是Python提供的求绝对值的函数 Python中的m
  • Django实现音乐网站 ⒅

    使用Python Django框架做一个音乐网站 本篇主要为歌单列表 歌单详情及推荐页 歌单内容改动 目录 歌单列表 设置路由 视图处理 模板渲染 歌单 单曲列表 设置路由 视图处理 模板渲染 推荐页 歌单列表 模板渲染修改 总结 歌单列表
  • C语言字节数

    bool 1字节 char 1字节 short 2字节 string 4字节 int 4字节 指针4字节 float 4字节 double 8字节 long 4或8字节 long long 8字节 long double 12字节 空类1字
  • ArcFace loss与其他改进loss对比

    ArcFace loss与其他改进loss对比 sphereFace A softmax cos ma 角度距离 cosFace AM softmax cosa m 余弦距离 ArcFace Arc softmax cos a m 角度距离
  • ICCV, ECCV, CVPR,IEEE的关系

    计算机视觉领域世界三大顶级会议分别为CVPR ICCV和ECCV CVPR CVPR 英文全称IEEE Conference on Computer Vision and Pattern Recognition 中文全称是国际计算机视觉与模
  • FeignClient中name和url属性的作用

    定义 feign是声明式的web service客户端 它让微服务之间的调用变得更简单了 类似controller调用service Spring Cloud集成了Ribbon和Eureka 可在使用Feign时提供负载均衡的http客户端
  • node-ffi ffi.Library往电脑窗口的任意光标处输入内容(user32.dll)window电脑

    node ffi ffi Library往电脑窗口的任意光标处输入内容 user32 dll window电脑 类似键盘输入法的效果 前提 遇到问题 解决问题了 补充安装库遇到的问题 类似键盘输入法的效果 我node项目和electron项
  • 语义分割评价指标mIOU的计算

    语义分割评价指标mIOU的计算 注意事项 这是针对重构了的语义分割网络 而不是之前的那个 所以不要询问原来的网络计算miou要怎么做 因为整个文件构架差距过大 建议使用新构架 学习前言 算一下语义分割的miou 做好生态链 什么是mIOU
  • 北大青鸟汉字注释机内码_北大青鸟消防主机如何编写汉字注释?

    北大青鸟消防主机汉字注释有两种 一种是利用编程调试软件进行编写文字注释 另一种是直接在消防主机上对照汉字机内码 进入系统进行编辑 下面小编跟大家介绍的是使用编程调试软件进行文字注释的方法 1 序号 项 序号 项自动生成 不需用户自己填写 2
  • 【SSO单点登录】JWT续签问题 && OAuth2.0 中的refreshToken刷新机制

    本篇速览 JWT续签问题 快过期时返回新的token refreshToken 如何判断refreshToken的有效性 扩展 OAuth2 0 中的refreshToken刷新机制 其他需要刷新token的情况 用户修改了角色权限 删除了
  • SQL优化之 not in

    not in select from dic region old a where a region code not in select b region code from dic region b PL SQL 执行 选择17 行 耗
  • 通过liquibase将PostgreSQL数据库导入到H2数据库

    1 背景 项目中使用的数据库是PostgreSQL 在做测试时 想使用H2代替 2 问题 2 1 保留字 在PostgreSQL中使用了几个H2的保留字 例如 end offset foreign 这些保留字是不能作为表的字段名 2 2 字
  • Java加解密的基础

    在Java的安全包中 包括了三部分内容 1 JCA JCE Java Cryptography Architecture JavaCryptography Extensions 2 JSSE Java Secure Sockets Exte