JAVA加密--JCA、JCE、CSP概念、体系架构与使用示例

本文详细介绍了Java Cryptography Architecture (JCA)和Java Cryptography Extension (JCE)的架构、功能,以及如何在Java应用中使用它们进行加密、解密、哈希和安全服务。提供了SUN、SunRsaSign、SunJSSE等提供者及其包含的算法实例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1 概念

JCA: Java密码体系结构 Java Cryptography Architecture
JCE(Java Cryptography Extension),在早期JDK版本中,由于受美国的密码出口条例约束,Java中涉及加解密功能的API被限制出口,所以Java中安全组件被分成了两部分: 不含加密功能的JCA(Java Cryptography Architecture )和含加密功能的JCE(Java Cryptography Extension)。现在JCE已经捆绑在JDK中,所以,这里JCE是JCA的一部分

JCA包含一个提供者【Provider】体系结构和一组用于数字签名,消息摘要(哈希),证书和证书验证,加密(对称/非对称块/流密码),密钥生成管理和安全随机数生成等等的API。
这些API允许开发人员将安全性轻松集成到应用程序代码中。

JCA包含两个软件组件:

  • 定义和支持Provider为其提供实现的加密服务的框架。 这个框架包含了诸如java.security,javax.crypto,javax.crypto.spec和javax.crypto.interfaces等软件包。
  • Sun,SunRsaSign,SunJCE等实际提供者都包含了具体的加密实现。

2 架构

2.1 加密服务提供者(CSP)

java.security.Provider是所有安全提供程序的基类。 每个CSP都包含这个类的一个实例,它包含了提供者的名字,并列出了它实现的所有安全服务/算法。 当需要特定算法的实例时,JCA框架会咨询提供者的数据库,如果找到合适的匹配项,则创建该实例。

Provider包含一个包(或一组包),为声明的加密算法提供具体的实现。 每个JDK安装都默认安装并配置了一个或多个提供程序。 其他提供者可以静态或动态添加(参见Provider和Security类)。 客户端可以配置其运行时环境来指定提供程序的首选顺序。 首选顺序是在没有请求特定提供者时提供者搜索请求的服务的顺序。

要使用JCA,应用程序只需要请求特定类型的对象(如MessageDigest)和特定的算法或服务(如“SHA-256”算法),并从一个已安装的提供者获取实现。 或者,程序可以请求来自特定提供者的对象。 每个提供者都有一个名字来引用它。

应用程序需要一个“AES”算法的javax.crypto.Cipher实例,并不关心使用哪个提供者。应用程序调用Cipher引擎类的getInstance()工厂方法,然后请求JCA框架查找支持“AES”的第一个提供程序实例。该框架会咨询每个已安装的提供者,并获取提供者类的提供者实例
在这里插入图片描述
在调用时,不指定提供者 和 指定提供者的调用流程:
在这里插入图片描述

2.2 provider 提供者

provider提供者,这里的全称是 Cryptographic Service Provider (CSP),是指实现一个或多个密码服务(如数字签名算法,消息摘要算法和密钥转换服务)的包或一组包。 每个JDK安装都默认安装并配置了一个或多个provider包。用户可以静态或动态添加其他provider。
JDK中的加密库出于历史原因,由几个不同的提供者实现:

  • SUN
  • SunRsaSign
  • SunEC
  • SunJSSE
  • SunJCE
  • SunJGSS
  • SunSASL
  • XMLDSig
  • SunPCSC
  • SunMSCAPI

java.security.Provider是所有安全提供程序的基类

获取提供者和算法的代码示例:

		System.out.println("|提供者|算法|");
        System.out.println("|:---|:---|");
        for(Provider provider: Security.getProviders()){
            for(Provider.Service service:provider.getServices()){
                System.out.println("|"+provider.getName()+"|"+service.getAlgorithm()+"|");
            }
        }

Engine类和算法

引擎类为特定类型的密码服务提供接口,而不依赖于特定的密码算法或提供者。 引擎需要提供如下功能:

  • 密码操作(加密,数字签名,消息摘要等),
  • 发生器或密码材料的转换器(密钥和算法参数)
  • 对象(密钥库或证书)封装了密码数据,可以在更高的抽象层使用。
引擎类功能
SecureRandom用于生成随机或伪随机数字。
MessageDigest用于计算指定数据的消息摘要(散列)。
Signature使用密钥初始化,这些签名用于签署数据并验证数字签
Cipher用密钥初始化,用于加密/解密数据。存在各种类型的算法
Message Authentication Codes(MAC)与MessageDigests一样,它们也会生成散列值,但是首先使用密钥初始化以保护消息的完整性。
KeyFactory用于将Key类型的现有不透明密钥转换为密钥规范(底层密钥材料的透明表示),反之亦然。
SecretKeyFactory用于将SecretKey类型的现有不透明加密密钥转换为密钥规范(底层密钥材料的透明表示),反之亦然。 SecretKeyFactorys是专门的KeyFactorys,只能创建密钥(对称)。
KeyPairGenerator用于生成一对适用于指定算法的公钥和私钥。
KeyGenerator用于生成与指定算法一起使用的新密钥。
KeyAgreement由两方或多方使用,商定和建立一个特定的密钥,用于特定的密码操作。
AlgorithmParameters用于存储特定算法的参数,包括参数编码和解码。
AlgorithmParameterGenerator用于生成适合于指定算法的一组AlgorithmParameters。
KeyStore用于创建和管理密钥库。密钥库是密钥的数据库。密钥库中的私钥具有与其关联的证书链,用于验证相应的公钥。密钥库还包含来自可信实体的证书。
CertificateFactory用于创建公钥证书和证书吊销列表(CRL)。
CertPathBuilder用于构建证书链(也称为证书路径)。
CertPathValidator用于验证证书链。
CertStore用于从存储库中检索证书和CRL。
注意生成器可以创建具有全新内容的对象,而工厂只能从现有材料(例如编码)中创建对象。

3 使用示例

3.1 MessageDigest使用示例

以md5加密,演示MessageDigest的使用

public static void main(String[] args) {
        byte[] content = "hello world".getBytes();
        System.out.println(DigestUtils.md5DigestAsHex(content));
        System.out.println(DigestUtils.digestAsHexString("MD5", content));

        for (String algName : Security.getAlgorithms("MessageDigest")) {
            System.out.println(algName + "==>" + DigestUtils.digestAsHexString(algName, content));
        }
    }

3.2 MessageDigest工具类

public class DigestUtils {

    private static final String MD5_ALGORITHM_NAME = "MD5";

    private static final char[] HEX_CHARS =
            {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};


    /**
     * Calculate the MD5 digest of the given bytes.
     *
     * @param bytes the bytes to calculate the digest over
     * @return the digest
     */
    public static byte[] md5Digest(byte[] bytes) {
        return digest(MD5_ALGORITHM_NAME, bytes);
    }

    /**
     * Return a hexadecimal string representation of the MD5 digest of the given bytes.
     *
     * @param bytes the bytes to calculate the digest over
     * @return a hexadecimal digest string
     */
    public static String md5DigestAsHex(byte[] bytes) {
        return digestAsHexString(MD5_ALGORITHM_NAME, bytes);
    }

    /**
     * Append a hexadecimal string representation of the MD5 digest of the given
     * bytes to the given {@link StringBuilder}.
     *
     * @param bytes   the bytes to calculate the digest over
     * @param builder the string builder to append the digest to
     * @return the given string builder
     */
    public static StringBuilder appendMd5DigestAsHex(byte[] bytes, StringBuilder builder) {
        return appendDigestAsHex(MD5_ALGORITHM_NAME, bytes, builder);
    }

    public static String digestAsHexString(String algorithm, byte[] bytes) {
        char[] hexDigest = digestAsHexChars(algorithm, bytes);
        return new String(hexDigest);
    }

    public static StringBuilder appendDigestAsHex(String algorithm, byte[] bytes, StringBuilder builder) {
        char[] hexDigest = digestAsHexChars(algorithm, bytes);
        return builder.append(hexDigest);
    }


    /**
     * Create a new {@link MessageDigest} with the given algorithm.
     * Necessary because {@code MessageDigest} is not thread-safe.
     */
    private static MessageDigest getDigest(String algorithm) {
        try {
            return MessageDigest.getInstance(algorithm);
        } catch (NoSuchAlgorithmException ex) {
            throw new IllegalStateException("Could not find MessageDigest with algorithm \"" + algorithm + "\"", ex);
        }
    }

    private static byte[] digest(String algorithm, byte[] bytes) {
        return getDigest(algorithm).digest(bytes);
    }

    private static char[] digestAsHexChars(String algorithm, byte[] bytes) {
        byte[] digest = digest(algorithm, bytes);
        return encodeHex(digest);
    }

    private static char[] encodeHex(byte[] bytes) {
        char[] chars = new char[32];
        for (int i = 0; i < chars.length; i = i + 2) {
            byte b = bytes[i / 2];
            chars[i] = HEX_CHARS[(b >>> 0x4) & 0xf];
            chars[i + 1] = HEX_CHARS[b & 0xf];
        }
        return chars;
    }

}

参考

【Java加密】JCA体系结构
Java –可用的MessageDigest算法列表
Java生成MD5的两种方式

provider及算法

提供者算法
SUNSHA1PRNG
SUNSHA1withDSA
SUNNONEwithDSA
SUNSHA224withDSA
SUNSHA256withDSA
SUNDSA
SUNMD2
SUNMD5
SUNSHA
SUNSHA-224
SUNSHA-256
SUNSHA-384
SUNSHA-512
SUNDSA
SUNDSA
SUNDSA
SUNX.509
SUNJKS
SUNCaseExactJKS
SUNDKS
SUNJavaPolicy
SUNJavaLoginConfig
SUNPKIX
SUNPKIX
SUNLDAP
SUNCollection
SUNcom.sun.security.IndexedCollection
SunRsaSignRSA
SunRsaSignRSA
SunRsaSignMD2withRSA
SunRsaSignMD5withRSA
SunRsaSignSHA1withRSA
SunRsaSignSHA224withRSA
SunRsaSignSHA256withRSA
SunRsaSignSHA384withRSA
SunRsaSignSHA512withRSA
SunECEC
SunECEC
SunECNONEwithECDSA
SunECSHA1withECDSA
SunECSHA224withECDSA
SunECSHA256withECDSA
SunECSHA384withECDSA
SunECSHA512withECDSA
SunECEC
SunECECDH
SunJSSERSA
SunJSSERSA
SunJSSEMD2withRSA
SunJSSEMD5withRSA
SunJSSESHA1withRSA
SunJSSEMD5andSHA1withRSA
SunJSSESunX509
SunJSSENewSunX509
SunJSSESunX509
SunJSSEPKIX
SunJSSETLSv1
SunJSSETLSv1.1
SunJSSETLSv1.2
SunJSSETLS
SunJSSEDefault
SunJSSEPKCS12
SunJCERSA
SunJCEDES
SunJCEDESede
SunJCEDESedeWrap
SunJCEPBEWithMD5AndDES
SunJCEPBEWithMD5AndTripleDES
SunJCEPBEWithSHA1AndDESede
SunJCEPBEWithSHA1AndRC2_40
SunJCEPBEWithSHA1AndRC2_128
SunJCEPBEWithSHA1AndRC4_40
SunJCEPBEWithSHA1AndRC4_128
SunJCEPBEWithHmacSHA1AndAES_128
SunJCEPBEWithHmacSHA224AndAES_128
SunJCEPBEWithHmacSHA256AndAES_128
SunJCEPBEWithHmacSHA384AndAES_128
SunJCEPBEWithHmacSHA512AndAES_128
SunJCEPBEWithHmacSHA1AndAES_256
SunJCEPBEWithHmacSHA224AndAES_256
SunJCEPBEWithHmacSHA256AndAES_256
SunJCEPBEWithHmacSHA384AndAES_256
SunJCEPBEWithHmacSHA512AndAES_256
SunJCEBlowfish
SunJCEAES
SunJCEAES_128/ECB/NoPadding
SunJCEAES_128/CBC/NoPadding
SunJCEAES_128/OFB/NoPadding
SunJCEAES_128/CFB/NoPadding
SunJCEAES_128/GCM/NoPadding
SunJCEAES_192/ECB/NoPadding
SunJCEAES_192/CBC/NoPadding
SunJCEAES_192/OFB/NoPadding
SunJCEAES_192/CFB/NoPadding
SunJCEAES_192/GCM/NoPadding
SunJCEAES_256/ECB/NoPadding
SunJCEAES_256/CBC/NoPadding
SunJCEAES_256/OFB/NoPadding
SunJCEAES_256/CFB/NoPadding
SunJCEAES_256/GCM/NoPadding
SunJCEAESWrap
SunJCEAESWrap_128
SunJCEAESWrap_192
SunJCEAESWrap_256
SunJCERC2
SunJCEARCFOUR
SunJCEDES
SunJCEDESede
SunJCEBlowfish
SunJCEAES
SunJCERC2
SunJCEARCFOUR
SunJCEHmacMD5
SunJCEHmacSHA1
SunJCEHmacSHA224
SunJCEHmacSHA256
SunJCEHmacSHA384
SunJCEHmacSHA512
SunJCEDiffieHellman
SunJCEDiffieHellman
SunJCEDiffieHellman
SunJCEDiffieHellman
SunJCEDES
SunJCEDESede
SunJCEPBE
SunJCEPBEWithMD5AndDES
SunJCEPBEWithMD5AndTripleDES
SunJCEPBEWithSHA1AndDESede
SunJCEPBEWithSHA1AndRC2_40
SunJCEPBEWithSHA1AndRC2_128
SunJCEPBEWithSHA1AndRC4_40
SunJCEPBEWithSHA1AndRC4_128
SunJCEPBES2
SunJCEPBEWithHmacSHA1AndAES_128
SunJCEPBEWithHmacSHA224AndAES_128
SunJCEPBEWithHmacSHA256AndAES_128
SunJCEPBEWithHmacSHA384AndAES_128
SunJCEPBEWithHmacSHA512AndAES_128
SunJCEPBEWithHmacSHA1AndAES_256
SunJCEPBEWithHmacSHA224AndAES_256
SunJCEPBEWithHmacSHA256AndAES_256
SunJCEPBEWithHmacSHA384AndAES_256
SunJCEPBEWithHmacSHA512AndAES_256
SunJCEBlowfish
SunJCEAES
SunJCEGCM
SunJCERC2
SunJCEOAEP
SunJCEDiffieHellman
SunJCEDES
SunJCEDESede
SunJCEPBEWithMD5AndDES
SunJCEPBEWithMD5AndTripleDES
SunJCEPBEWithSHA1AndDESede
SunJCEPBEWithSHA1AndRC2_40
SunJCEPBEWithSHA1AndRC2_128
SunJCEPBEWithSHA1AndRC4_40
SunJCEPBEWithSHA1AndRC4_128
SunJCEPBEWithHmacSHA1AndAES_128
SunJCEPBEWithHmacSHA224AndAES_128
SunJCEPBEWithHmacSHA256AndAES_128
SunJCEPBEWithHmacSHA384AndAES_128
SunJCEPBEWithHmacSHA512AndAES_128
SunJCEPBEWithHmacSHA1AndAES_256
SunJCEPBEWithHmacSHA224AndAES_256
SunJCEPBEWithHmacSHA256AndAES_256
SunJCEPBEWithHmacSHA384AndAES_256
SunJCEPBEWithHmacSHA512AndAES_256
SunJCEPBKDF2WithHmacSHA1
SunJCEPBKDF2WithHmacSHA224
SunJCEPBKDF2WithHmacSHA256
SunJCEPBKDF2WithHmacSHA384
SunJCEPBKDF2WithHmacSHA512
SunJCEHmacMD5
SunJCEHmacSHA1
SunJCEHmacSHA224
SunJCEHmacSHA256
SunJCEHmacSHA384
SunJCEHmacSHA512
SunJCEHmacPBESHA1
SunJCEPBEWithHmacSHA1
SunJCEPBEWithHmacSHA224
SunJCEPBEWithHmacSHA256
SunJCEPBEWithHmacSHA384
SunJCEPBEWithHmacSHA512
SunJCESslMacMD5
SunJCESslMacSHA1
SunJCEJCEKS
SunJCESunTlsPrf
SunJCESunTls12Prf
SunJCESunTlsMasterSecret
SunJCESunTlsKeyMaterial
SunJCESunTlsRsaPremasterSecret
SunJGSS1.2.840.113554.1.2.2
SunJGSS1.3.6.1.5.5.2
SunSASLDIGEST-MD5
SunSASLNTLM
SunSASLGSSAPI
SunSASLEXTERNAL
SunSASLPLAIN
SunSASLCRAM-MD5
SunSASLCRAM-MD5
SunSASLGSSAPI
SunSASLDIGEST-MD5
SunSASLNTLM
XMLDSighttp://www.w3.org/2006/12/xml-c14n11#WithComments
XMLDSighttp://www.w3.org/2000/09/xmldsig#base64
XMLDSighttp://www.w3.org/TR/1999/REC-xslt-19991116
XMLDSighttp://www.w3.org/2001/10/xml-exc-c14n#
XMLDSighttp://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments
XMLDSighttp://www.w3.org/2000/09/xmldsig#enveloped-signature
XMLDSighttp://www.w3.org/2002/06/xmldsig-filter2
XMLDSigDOM
XMLDSighttp://www.w3.org/TR/2001/REC-xml-c14n-20010315
XMLDSighttp://www.w3.org/2001/10/xml-exc-c14n#WithComments
XMLDSighttp://www.w3.org/2006/12/xml-c14n11
XMLDSighttp://www.w3.org/TR/1999/REC-xpath-19991116
XMLDSigDOM
SunPCSCPC/SC
SunMSCAPIWindows-PRNG
SunMSCAPIWindows-MY
SunMSCAPIWindows-ROOT
SunMSCAPINONEwithRSA
SunMSCAPISHA1withRSA
SunMSCAPISHA256withRSA
SunMSCAPISHA384withRSA
SunMSCAPISHA512withRSA
SunMSCAPIMD5withRSA
SunMSCAPIMD2withRSA
SunMSCAPIRSA
SunMSCAPIRSA
SunMSCAPIRSA/ECB/PKCS1Padding
### 回答1: Apache Flume是基于数据流的分布式系统,专门用于从各种非结构化数据源收集,聚合和移动大量数据,它支持多种数据源的连接和数据交付到多种数据存储库。该软件是Apache软件基金会下的一个顶级项目,它是一个稳定、高效和可靠的工具,可以帮助企业实现数据的有效管理和分析。 apache-flume-1.9.0-bin.tar.gz下载是通过Apache官网提供的链接来进行下载的。下载完成后需要进行安装和相关配置,以便能够其他数据源进行连接和数据交付。该软件的安装和配置较为复杂,需要具备一定的计算机技能和数据管理知识。 下载完成后,用户需要解压该文件,并在用户设置的文件夹中配置flume-env.sh和flume.conf文件。配置后,即可启动Flume服务,进行数据的收集和聚合操作。在使用过程中,用户可以根据实际需要,选择不同的数据源和文件存储方式,以满足企业数据管理和分析的需求。 总之,Apache Flume是一个强大的数据管理和分析工具,具有广泛的应用和丰富的功能。但在使用前,用户需要详细了解该软件的安装和配置过程,并具备一定的技能和知识储备,以确保其能够正确地使用和操作。 ### 回答2: Apache Flume是一个分布式、可靠、高效的数据采集、聚合和传输系统,在数据处理中应用广泛。而apache-flume-1.9.0-bin.tar.gz则是Apache Flume的官方发布版本,其中bin表示此版本是可执行程序,tar.gz是一种压缩格式。 要下载apache-flume-1.9.0-bin.tar.gz,首先需要前往Apache Flume的官网,然后找到下载页面。在下载页面中可以选择下载镜像站点以及下载apache-flume-1.9.0-bin.tar.gz的链接。用户可以根据自己的网络情况、所在地区等因素选择镜像站点并点击相应的链接进行下载。 下载完成后,用户可以使用解压软件将apache-flume-1.9.0-bin.tar.gz解压到任何想要安装的目录中。解压完成后,在bin目录下可以找到flume-ng的可执行文件,即可尝试运行Flume。 值得注意的是,Apache Flume是一个开源项目,因此用户可以访问其源代码,也可以参到项目的开发中来。该软件的最新版本、文档等信息也可在官网上获得。 ### 回答3: Apache Flume是一款优秀的分布式高可靠日志收集聚合工具,可以将数据从各种不同的数据源采集并集中到集中式的Hadoop数据仓库中。而Apache Flume 1.9.0-bin.tar.gz是Apache Flume的最新版本程序包,包含了Flume各种组件的可执行文件、示例配置文件、JAVA API等组件。 如果要下载Apache Flume 1.9.0-bin.tar.gz,可以先访问Apache Flume的官网,找到需要下载的地方,可以选择使用浏览器直接下载或使用命令行工具wget下载到本地,解压缩后将Flume各个组件配置好后就可以使用了。 需要注意的是,安装Apache Flume还需要为其配置相应的环境(例如配置JDK环境变量等),并进行一些必要的安全设置。而且对于不同的数据源Hadoop生态系统版本,Apache Flume部署和配置也会略有不同。因此,在使用过程中,应该先学习Apache Flume的相关知识,并根据情况灵活应用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

enjoy编程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值