JAVA加密--JCA、JCE、CSP概念、体系架构与使用示例
讲解JCA、JCE、CSP概念及JCA的体系架构,并以MD5加密,演示如何基于JCA进行数据加密
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及算法
提供者 | 算法 |
---|---|
SUN | SHA1PRNG |
SUN | SHA1withDSA |
SUN | NONEwithDSA |
SUN | SHA224withDSA |
SUN | SHA256withDSA |
SUN | DSA |
SUN | MD2 |
SUN | MD5 |
SUN | SHA |
SUN | SHA-224 |
SUN | SHA-256 |
SUN | SHA-384 |
SUN | SHA-512 |
SUN | DSA |
SUN | DSA |
SUN | DSA |
SUN | X.509 |
SUN | JKS |
SUN | CaseExactJKS |
SUN | DKS |
SUN | JavaPolicy |
SUN | JavaLoginConfig |
SUN | PKIX |
SUN | PKIX |
SUN | LDAP |
SUN | Collection |
SUN | com.sun.security.IndexedCollection |
SunRsaSign | RSA |
SunRsaSign | RSA |
SunRsaSign | MD2withRSA |
SunRsaSign | MD5withRSA |
SunRsaSign | SHA1withRSA |
SunRsaSign | SHA224withRSA |
SunRsaSign | SHA256withRSA |
SunRsaSign | SHA384withRSA |
SunRsaSign | SHA512withRSA |
SunEC | EC |
SunEC | EC |
SunEC | NONEwithECDSA |
SunEC | SHA1withECDSA |
SunEC | SHA224withECDSA |
SunEC | SHA256withECDSA |
SunEC | SHA384withECDSA |
SunEC | SHA512withECDSA |
SunEC | EC |
SunEC | ECDH |
SunJSSE | RSA |
SunJSSE | RSA |
SunJSSE | MD2withRSA |
SunJSSE | MD5withRSA |
SunJSSE | SHA1withRSA |
SunJSSE | MD5andSHA1withRSA |
SunJSSE | SunX509 |
SunJSSE | NewSunX509 |
SunJSSE | SunX509 |
SunJSSE | PKIX |
SunJSSE | TLSv1 |
SunJSSE | TLSv1.1 |
SunJSSE | TLSv1.2 |
SunJSSE | TLS |
SunJSSE | Default |
SunJSSE | PKCS12 |
SunJCE | RSA |
SunJCE | DES |
SunJCE | DESede |
SunJCE | DESedeWrap |
SunJCE | PBEWithMD5AndDES |
SunJCE | PBEWithMD5AndTripleDES |
SunJCE | PBEWithSHA1AndDESede |
SunJCE | PBEWithSHA1AndRC2_40 |
SunJCE | PBEWithSHA1AndRC2_128 |
SunJCE | PBEWithSHA1AndRC4_40 |
SunJCE | PBEWithSHA1AndRC4_128 |
SunJCE | PBEWithHmacSHA1AndAES_128 |
SunJCE | PBEWithHmacSHA224AndAES_128 |
SunJCE | PBEWithHmacSHA256AndAES_128 |
SunJCE | PBEWithHmacSHA384AndAES_128 |
SunJCE | PBEWithHmacSHA512AndAES_128 |
SunJCE | PBEWithHmacSHA1AndAES_256 |
SunJCE | PBEWithHmacSHA224AndAES_256 |
SunJCE | PBEWithHmacSHA256AndAES_256 |
SunJCE | PBEWithHmacSHA384AndAES_256 |
SunJCE | PBEWithHmacSHA512AndAES_256 |
SunJCE | Blowfish |
SunJCE | AES |
SunJCE | AES_128/ECB/NoPadding |
SunJCE | AES_128/CBC/NoPadding |
SunJCE | AES_128/OFB/NoPadding |
SunJCE | AES_128/CFB/NoPadding |
SunJCE | AES_128/GCM/NoPadding |
SunJCE | AES_192/ECB/NoPadding |
SunJCE | AES_192/CBC/NoPadding |
SunJCE | AES_192/OFB/NoPadding |
SunJCE | AES_192/CFB/NoPadding |
SunJCE | AES_192/GCM/NoPadding |
SunJCE | AES_256/ECB/NoPadding |
SunJCE | AES_256/CBC/NoPadding |
SunJCE | AES_256/OFB/NoPadding |
SunJCE | AES_256/CFB/NoPadding |
SunJCE | AES_256/GCM/NoPadding |
SunJCE | AESWrap |
SunJCE | AESWrap_128 |
SunJCE | AESWrap_192 |
SunJCE | AESWrap_256 |
SunJCE | RC2 |
SunJCE | ARCFOUR |
SunJCE | DES |
SunJCE | DESede |
SunJCE | Blowfish |
SunJCE | AES |
SunJCE | RC2 |
SunJCE | ARCFOUR |
SunJCE | HmacMD5 |
SunJCE | HmacSHA1 |
SunJCE | HmacSHA224 |
SunJCE | HmacSHA256 |
SunJCE | HmacSHA384 |
SunJCE | HmacSHA512 |
SunJCE | DiffieHellman |
SunJCE | DiffieHellman |
SunJCE | DiffieHellman |
SunJCE | DiffieHellman |
SunJCE | DES |
SunJCE | DESede |
SunJCE | PBE |
SunJCE | PBEWithMD5AndDES |
SunJCE | PBEWithMD5AndTripleDES |
SunJCE | PBEWithSHA1AndDESede |
SunJCE | PBEWithSHA1AndRC2_40 |
SunJCE | PBEWithSHA1AndRC2_128 |
SunJCE | PBEWithSHA1AndRC4_40 |
SunJCE | PBEWithSHA1AndRC4_128 |
SunJCE | PBES2 |
SunJCE | PBEWithHmacSHA1AndAES_128 |
SunJCE | PBEWithHmacSHA224AndAES_128 |
SunJCE | PBEWithHmacSHA256AndAES_128 |
SunJCE | PBEWithHmacSHA384AndAES_128 |
SunJCE | PBEWithHmacSHA512AndAES_128 |
SunJCE | PBEWithHmacSHA1AndAES_256 |
SunJCE | PBEWithHmacSHA224AndAES_256 |
SunJCE | PBEWithHmacSHA256AndAES_256 |
SunJCE | PBEWithHmacSHA384AndAES_256 |
SunJCE | PBEWithHmacSHA512AndAES_256 |
SunJCE | Blowfish |
SunJCE | AES |
SunJCE | GCM |
SunJCE | RC2 |
SunJCE | OAEP |
SunJCE | DiffieHellman |
SunJCE | DES |
SunJCE | DESede |
SunJCE | PBEWithMD5AndDES |
SunJCE | PBEWithMD5AndTripleDES |
SunJCE | PBEWithSHA1AndDESede |
SunJCE | PBEWithSHA1AndRC2_40 |
SunJCE | PBEWithSHA1AndRC2_128 |
SunJCE | PBEWithSHA1AndRC4_40 |
SunJCE | PBEWithSHA1AndRC4_128 |
SunJCE | PBEWithHmacSHA1AndAES_128 |
SunJCE | PBEWithHmacSHA224AndAES_128 |
SunJCE | PBEWithHmacSHA256AndAES_128 |
SunJCE | PBEWithHmacSHA384AndAES_128 |
SunJCE | PBEWithHmacSHA512AndAES_128 |
SunJCE | PBEWithHmacSHA1AndAES_256 |
SunJCE | PBEWithHmacSHA224AndAES_256 |
SunJCE | PBEWithHmacSHA256AndAES_256 |
SunJCE | PBEWithHmacSHA384AndAES_256 |
SunJCE | PBEWithHmacSHA512AndAES_256 |
SunJCE | PBKDF2WithHmacSHA1 |
SunJCE | PBKDF2WithHmacSHA224 |
SunJCE | PBKDF2WithHmacSHA256 |
SunJCE | PBKDF2WithHmacSHA384 |
SunJCE | PBKDF2WithHmacSHA512 |
SunJCE | HmacMD5 |
SunJCE | HmacSHA1 |
SunJCE | HmacSHA224 |
SunJCE | HmacSHA256 |
SunJCE | HmacSHA384 |
SunJCE | HmacSHA512 |
SunJCE | HmacPBESHA1 |
SunJCE | PBEWithHmacSHA1 |
SunJCE | PBEWithHmacSHA224 |
SunJCE | PBEWithHmacSHA256 |
SunJCE | PBEWithHmacSHA384 |
SunJCE | PBEWithHmacSHA512 |
SunJCE | SslMacMD5 |
SunJCE | SslMacSHA1 |
SunJCE | JCEKS |
SunJCE | SunTlsPrf |
SunJCE | SunTls12Prf |
SunJCE | SunTlsMasterSecret |
SunJCE | SunTlsKeyMaterial |
SunJCE | SunTlsRsaPremasterSecret |
SunJGSS | 1.2.840.113554.1.2.2 |
SunJGSS | 1.3.6.1.5.5.2 |
SunSASL | DIGEST-MD5 |
SunSASL | NTLM |
SunSASL | GSSAPI |
SunSASL | EXTERNAL |
SunSASL | PLAIN |
SunSASL | CRAM-MD5 |
SunSASL | CRAM-MD5 |
SunSASL | GSSAPI |
SunSASL | DIGEST-MD5 |
SunSASL | NTLM |
XMLDSig | http://www.w3.org/2006/12/xml-c14n11#WithComments |
XMLDSig | http://www.w3.org/2000/09/xmldsig#base64 |
XMLDSig | http://www.w3.org/TR/1999/REC-xslt-19991116 |
XMLDSig | http://www.w3.org/2001/10/xml-exc-c14n# |
XMLDSig | http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments |
XMLDSig | http://www.w3.org/2000/09/xmldsig#enveloped-signature |
XMLDSig | http://www.w3.org/2002/06/xmldsig-filter2 |
XMLDSig | DOM |
XMLDSig | http://www.w3.org/TR/2001/REC-xml-c14n-20010315 |
XMLDSig | http://www.w3.org/2001/10/xml-exc-c14n#WithComments |
XMLDSig | http://www.w3.org/2006/12/xml-c14n11 |
XMLDSig | http://www.w3.org/TR/1999/REC-xpath-19991116 |
XMLDSig | DOM |
SunPCSC | PC/SC |
SunMSCAPI | Windows-PRNG |
SunMSCAPI | Windows-MY |
SunMSCAPI | Windows-ROOT |
SunMSCAPI | NONEwithRSA |
SunMSCAPI | SHA1withRSA |
SunMSCAPI | SHA256withRSA |
SunMSCAPI | SHA384withRSA |
SunMSCAPI | SHA512withRSA |
SunMSCAPI | MD5withRSA |
SunMSCAPI | MD2withRSA |
SunMSCAPI | RSA |
SunMSCAPI | RSA |
SunMSCAPI | RSA/ECB/PKCS1Padding |
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)