项目里有各种加密方法,但从来没有仔细研究过。一般只是copy。这几天遇到一些问题,看了一下加密代码,觉得有些疑惑。

    我们知道jdk已经为我们包装好了很多的算法。但究竟包装了哪些算法,怎么去掉这些算法我并没有去查过。今天跟了一下源码,大概知道了。

    首先要从下面这几行代码说起:

KeyGenerator kgen = KeyGenerator.getInstance("AES");

SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");

java.security.MessageDigest md = java.security.MessageDigest.getInstance("MD5");

    对于AES加密,我们用KeyGenerator kgen = KeyGenerator.getInstance("AES");,MD5我们用java.security.MessageDigest md = java.security.MessageDigest.getInstance("MD5");,这里从方法上看出java类是通过一个算法名称去找的,比如AES,但源码中并没有把算法名称包装为枚举,我们无法得知KeyGenerator除了有AES算法,还能获得那些算法,而且如何获得KeyGenerator的算法名称,比如AES不全是大写会不会有问题,KeyGenerator是不是有MD5等等。

    打开KeyGenerator.getInstance()方法,看其源码

public static final KeyGenerator getInstance(String paramString)
throws NoSuchAlgorithmException
{
return new KeyGenerator(paramString);
}

    我们发现直接调用了构造方法,查看构造方法:

  private KeyGenerator(String paramString)
throws NoSuchAlgorithmException
{
this.algorithm = paramString; List localList = GetInstance.getServices("KeyGenerator", paramString);
this.serviceIterator = localList.iterator();
this.initType = 1;
if (nextSpi(null, false) == null) {
throw new NoSuchAlgorithmException(paramString + " KeyGenerator not available");
}
if ((!skipDebug) && (pdebug != null)) {
pdebug.println("KeyGenerator." + paramString + " algorithm from: " + this.provider
.getName());
}
}

    构造方法其实是通过GetInstance.getServices("KeyGenerator", paramString)去找到,继续跟进

  public Provider.Service getService(String paramString1, String paramString2)
{
for (int i = 0; i < this.configs.length; i++)
{
Provider localProvider = getProvider(i);
Provider.Service localService = localProvider.getService(paramString1, paramString2);
if (localService != null) {
return localService;
}
}
return null;
}

    GetInstance.getServices其实是遍历所有的Provider,然后按顺序返回第一个有这个算法服务的Provide的算法服务(Provider.Service)。这里可以看出,寻找服务需要两个参数,第一个参数是type,比如"KeyGenerator",第二个是算法名称,“AES”。那现在我们只要知道有哪些Provide,每个Provide里有哪些Provider.Service就可以了。

    在jdk的API中,查看 KeyGenerator.getInstance方法,其中给了我们提示:

aaarticlea/png;base64,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" alt="" />

    我们可以本地写一个方法遍历jdk所有的算法:

package com.hongkang.test;

import java.security.Provider;
import java.security.Security;
import java.security.Provider.Service; public class TestSecurity { public static void main(String[] args) {
Provider[] providers = Security.getProviders();
for(Provider p:providers){
System.out.println("provider name:"+p.getName());
for(Service s:p.getServices()){
System.out.println("类型:"+s.getType()+",算法:"+s.getAlgorithm());
}
System.out.println("--------------------------");
}
}
}

输出结果:

provider name:SUN
类型:SecureRandom,算法:SHA1PRNG
类型:Signature,算法:SHA1withDSA
类型:Signature,算法:NONEwithDSA
类型:KeyPairGenerator,算法:DSA
类型:MessageDigest,算法:MD2
类型:MessageDigest,算法:MD5
类型:MessageDigest,算法:SHA
类型:MessageDigest,算法:SHA-256
类型:MessageDigest,算法:SHA-384
类型:MessageDigest,算法:SHA-512
类型:AlgorithmParameterGenerator,算法:DSA
类型:AlgorithmParameters,算法:DSA
类型:KeyFactory,算法:DSA
类型:CertificateFactory,算法:X.509
类型:KeyStore,算法:JKS
类型:KeyStore,算法:CaseExactJKS
类型:Policy,算法:JavaPolicy
类型:Configuration,算法:JavaLoginConfig
类型:CertPathBuilder,算法:PKIX
类型:CertPathValidator,算法:PKIX
类型:CertStore,算法:LDAP
类型:CertStore,算法:Collection
类型:CertStore,算法:com.sun.security.IndexedCollection
--------------------------
provider name:SunRsaSign
类型:KeyFactory,算法:RSA
类型:KeyPairGenerator,算法:RSA
类型:Signature,算法:MD2withRSA
类型:Signature,算法:MD5withRSA
类型:Signature,算法:SHA1withRSA
类型:Signature,算法:SHA256withRSA
类型:Signature,算法:SHA384withRSA
类型:Signature,算法:SHA512withRSA
--------------------------
provider name:SunEC
类型:KeyFactory,算法:EC
类型:AlgorithmParameters,算法:EC
类型:Signature,算法:NONEwithECDSA
类型:Signature,算法:SHA1withECDSA
类型:Signature,算法:SHA256withECDSA
类型:Signature,算法:SHA384withECDSA
类型:Signature,算法:SHA512withECDSA
类型:KeyPairGenerator,算法:EC
类型:KeyAgreement,算法:ECDH
--------------------------
provider name:SunJSSE
类型:KeyFactory,算法:RSA
类型:KeyPairGenerator,算法:RSA
类型:Signature,算法:MD2withRSA
类型:Signature,算法:MD5withRSA
类型:Signature,算法:SHA1withRSA
类型:Signature,算法:MD5andSHA1withRSA
类型:KeyManagerFactory,算法:SunX509
类型:KeyManagerFactory,算法:NewSunX509
类型:TrustManagerFactory,算法:SunX509
类型:TrustManagerFactory,算法:PKIX
类型:SSLContext,算法:TLSv1
类型:SSLContext,算法:TLSv1.1
类型:SSLContext,算法:TLSv1.2
类型:SSLContext,算法:Default
类型:KeyStore,算法:PKCS12
--------------------------
provider name:SunJCE
类型:Cipher,算法:RSA
类型:Cipher,算法:DES
类型:Cipher,算法:DESede
类型:Cipher,算法:DESedeWrap
类型:Cipher,算法:PBEWithMD5AndDES
类型:Cipher,算法:PBEWithMD5AndTripleDES
类型:Cipher,算法:PBEWithSHA1AndRC2_40
类型:Cipher,算法:PBEWithSHA1AndDESede
类型:Cipher,算法:Blowfish
类型:Cipher,算法:AES
类型:Cipher,算法:AESWrap
类型:Cipher,算法:RC2
类型:Cipher,算法:ARCFOUR
类型:KeyGenerator,算法:DES
类型:KeyGenerator,算法:DESede
类型:KeyGenerator,算法:Blowfish
类型:KeyGenerator,算法:AES
类型:KeyGenerator,算法:RC2
类型:KeyGenerator,算法:ARCFOUR
类型:KeyGenerator,算法:HmacMD5
类型:KeyGenerator,算法:HmacSHA1
类型:KeyGenerator,算法:HmacSHA256
类型:KeyGenerator,算法:HmacSHA384
类型:KeyGenerator,算法:HmacSHA512
类型:KeyPairGenerator,算法:DiffieHellman
类型:AlgorithmParameterGenerator,算法:DiffieHellman
类型:KeyAgreement,算法:DiffieHellman
类型:AlgorithmParameters,算法:DiffieHellman
类型:AlgorithmParameters,算法:DES
类型:AlgorithmParameters,算法:DESede
类型:AlgorithmParameters,算法:PBE
类型:AlgorithmParameters,算法:PBEWithMD5AndDES
类型:AlgorithmParameters,算法:PBEWithMD5AndTripleDES
类型:AlgorithmParameters,算法:PBEWithSHA1AndDESede
类型:AlgorithmParameters,算法:PBEWithSHA1AndRC2_40
类型:AlgorithmParameters,算法:Blowfish
类型:AlgorithmParameters,算法:AES
类型:AlgorithmParameters,算法:RC2
类型:AlgorithmParameters,算法:OAEP
类型:KeyFactory,算法:DiffieHellman
类型:SecretKeyFactory,算法:DES
类型:SecretKeyFactory,算法:DESede
类型:SecretKeyFactory,算法:PBEWithMD5AndDES
类型:SecretKeyFactory,算法:PBEWithMD5AndTripleDES
类型:SecretKeyFactory,算法:PBEWithSHA1AndDESede
类型:SecretKeyFactory,算法:PBEWithSHA1AndRC2_40
类型:SecretKeyFactory,算法:PBKDF2WithHmacSHA1
类型:Mac,算法:HmacMD5
类型:Mac,算法:HmacSHA1
类型:Mac,算法:HmacSHA256
类型:Mac,算法:HmacSHA384
类型:Mac,算法:HmacSHA512
类型:Mac,算法:HmacPBESHA1
类型:Mac,算法:SslMacMD5
类型:Mac,算法:SslMacSHA1
类型:KeyStore,算法:JCEKS
类型:KeyGenerator,算法:SunTlsPrf
类型:KeyGenerator,算法:SunTls12Prf
类型:KeyGenerator,算法:SunTlsMasterSecret
类型:KeyGenerator,算法:SunTlsKeyMaterial
类型:KeyGenerator,算法:SunTlsRsaPremasterSecret
--------------------------
provider name:SunJGSS
类型:GssApiMechanism,算法:1.2.840.113554.1.2.2
类型:GssApiMechanism,算法:1.3.6.1.5.5.2
--------------------------
provider name:SunSASL
类型:SaslClientFactory,算法:DIGEST-MD5
类型:SaslClientFactory,算法:NTLM
类型:SaslClientFactory,算法:GSSAPI
类型:SaslClientFactory,算法:EXTERNAL
类型:SaslClientFactory,算法:PLAIN
类型:SaslClientFactory,算法:CRAM-MD5
类型:SaslServerFactory,算法:CRAM-MD5
类型:SaslServerFactory,算法:GSSAPI
类型:SaslServerFactory,算法:DIGEST-MD5
类型:SaslServerFactory,算法:NTLM
--------------------------
provider name:XMLDSig
类型:TransformService,算法:http://www.w3.org/2002/06/xmldsig-filter2
类型:TransformService,算法:http://www.w3.org/2000/09/xmldsig#enveloped-signature
类型:TransformService,算法:http://www.w3.org/2001/10/xml-exc-c14n#WithComments
类型:TransformService,算法:http://www.w3.org/2001/10/xml-exc-c14n#
类型:TransformService,算法:http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments
类型:XMLSignatureFactory,算法:DOM
类型:TransformService,算法:http://www.w3.org/2006/12/xml-c14n11
类型:TransformService,算法:http://www.w3.org/2000/09/xmldsig#base64
类型:TransformService,算法:http://www.w3.org/TR/2001/REC-xml-c14n-20010315
类型:TransformService,算法:http://www.w3.org/TR/1999/REC-xpath-19991116
类型:TransformService,算法:http://www.w3.org/TR/1999/REC-xslt-19991116
类型:TransformService,算法:http://www.w3.org/2006/12/xml-c14n11#WithComments
类型:KeyInfoFactory,算法:DOM
--------------------------
provider name:SunPCSC
类型:TerminalFactory,算法:PC/SC
--------------------------
provider name:SunMSCAPI
类型:SecureRandom,算法:Windows-PRNG
类型:KeyStore,算法:Windows-MY
类型:KeyStore,算法:Windows-ROOT
类型:Signature,算法:NONEwithRSA
类型:Signature,算法:SHA1withRSA
类型:Signature,算法:SHA256withRSA
类型:Signature,算法:SHA384withRSA
类型:Signature,算法:SHA512withRSA
类型:Signature,算法:MD5withRSA
类型:Signature,算法:MD2withRSA
类型:KeyPairGenerator,算法:RSA
类型:Cipher,算法:RSA
类型:Cipher,算法:RSA/ECB/PKCS1Padding
--------------------------

通过观察,我们发现算法的类型,基本都对应java的一个类。算法类基本在jce.jar和rt.jar中。从这个结果中我们基本就能自己找算法了,比如要用MD5,在上面列表中发现类型是MessageDigest,则

MessageDigest md5 = MessageDigest.getInstance("MD5");

再仔细查看java.security.Provider类源码,发现此类在初始时就已经将这些算法类型初始化了,

 static
{
addEngine("AlgorithmParameterGenerator", false, null);
addEngine("AlgorithmParameters", false, null);
addEngine("KeyFactory", false, null);
addEngine("KeyPairGenerator", false, null);
addEngine("KeyStore", false, null);
addEngine("MessageDigest", false, null);
addEngine("SecureRandom", false, null);
addEngine("Signature", true, null);
addEngine("CertificateFactory", false, null);
addEngine("CertPathBuilder", false, null);
addEngine("CertPathValidator", false, null);
addEngine("CertStore", false, "java.security.cert.CertStoreParameters");
addEngine("Cipher", true, null);
addEngine("ExemptionMechanism", false, null);
addEngine("Mac", true, null);
addEngine("KeyAgreement", true, null);
addEngine("KeyGenerator", false, null);
addEngine("SecretKeyFactory", false, null);
addEngine("KeyManagerFactory", false, null);
addEngine("SSLContext", false, null);
addEngine("TrustManagerFactory", false, null);
addEngine("GssApiMechanism", false, null);
addEngine("SaslClientFactory", false, null);
addEngine("SaslServerFactory", false, null);
addEngine("Policy", false, "java.security.Policy$Parameters");
addEngine("Configuration", false, "javax.security.auth.login.Configuration$Parameters");
addEngine("XMLSignatureFactory", false, null);
addEngine("KeyInfoFactory", false, null);
addEngine("TransformService", false, null);
addEngine("TerminalFactory", false, "java.lang.Object");
} //还对大小写做了容错处理
  private static void addEngine(String paramString1, boolean paramBoolean, String paramString2)
  {
    EngineDescription localEngineDescription = new EngineDescription(paramString1, paramBoolean, paramString2);
    knownEngines.put(paramString1.toLowerCase(Locale.ENGLISH), localEngineDescription);
    knownEngines.put(paramString1, localEngineDescription);
  }

不过遗憾的是并没有找到AES这类算法是怎么初始化的。但是经测试,即便使用的不是大写,或者上面列表中列出的标准写法,也能正常获取,比如:

KeyGenerator kgen = KeyGenerator.getInstance("aEs");

也能正常执行。

java加密类型和算法名称的更多相关文章

  1. 记一次Java加密加签算法到php的坑

    此文为本人原创首发于 http://www.35coder.com/convert_encryption_codes_to_php/. 写代码的经历中,总少不了与外部的程序对接,一旦有这样的事,往往周 ...

  2. java 加密解密工具类(实用!!!)

    最近发现了一个加密解密的好例子,很方便使用,可以作为平时开发的工具集,记录一下. package com.sh.springboottdemo2.util; import com.sun.org.ap ...

  3. java sm4国密算法加密、解密

      java sm4国密算法加密.解密 CreationTime--2018年7月5日09点20分 Author:Marydon 1.准备工作 所需jar包: bcprov-jdk15on-1.59. ...

  4. 【转】Java Cipher类 DES算法(加密与解密)

    Java Cipher类 DES算法(加密与解密) 1.加密解密类 import java.security.*; import javax.crypto.*; import java.io.*; / ...

  5. JAVA实现AES的加密和解密算法

    原文 JAVA实现AES的加密和解密算法 import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import ja ...

  6. 【java】java获取对象属性类型、属性名称、属性值

    java获取对象属性类型.属性名称.属性值 获取属性 修饰符:[在Field[]循环中使用] String modifier = Modifier.toString(fields[i].getModi ...

  7. java加密解密算法位运算

    一.实例说明 本实例通过位运算的异或运算符 “ ^ ” 把字符串与一个指定的值进行异或运算,从而改变每个字符串中字符的值,这样就可以得到一个加密后的字符串.当把加密后的字符串作为程序输入内容,异或运算 ...

  8. Java中使用RSA算法加密

    Java中使用RSA算法加密 概述 RSA加密算法是一种非对称加密算法 RSA加密的方式 使用公钥加密的数据,利用私钥进行解密 使用私钥加密的数据,利用公钥进行解密 RSA是一对密钥.分别是公钥和私钥 ...

  9. Java Security:Java加密框架(JCA)简要说明

    加密服务总是关联到一个特定的算法或类型,它既提供了密码操作(如Digital Signature或MessageDigest),生成或供应所需的加密材料(Key或Parameters)加密操作,也会以 ...

随机推荐

  1. java基础(十五)集合(二)

    这里有我之前上课总结的一些知识点以及代码大部分是老师讲的笔记 个人认为是非常好的,,也是比较经典的内容,真诚的希望这些对于那些想学习的人有所帮助! 由于代码是分模块的上传非常的不便.也比较多,讲的也是 ...

  2. 进程与线程(7) 进程间通信之信号量 (java os)

    花3分钟浏览一下: http://blog.csdn.net/liu765023051/article/details/8067601 1.生产者,消费者的列子. 2.互斥和同步到底什么东西? 互斥是 ...

  3. GPU 的硬件基本概念,Cuda和Opencl名词关系对应

    GPU 的硬件基本概念 Nvidia的版本: 实际上在 nVidia 的 GPU 里,最基本的处理单元是所谓的 SP(Streaming Processor),而一颗 nVidia 的 GPU 里,会 ...

  4. Redis Desktop Manager桌面管理工具

    Redis Desktop Manager桌面管理工具,方便管理我们放在redis中的各个缓存 及16个数据库 http://redisdesktop.com/download

  5. 关于wordpress在修改固定链接后,总显示Not Found的问题

    参考来源: http://chinablog.blog.51cto.com/276793/280278 一.问题背景 使用wordpress搭建网站,为了让文章URL看起来漂亮一点,wordpress ...

  6. gwt中java与js的相互调用

    1. java通过jsni调用内部js Button button = new Button("java调用内部jsni的js方法"); button.addClickHandle ...

  7. Nginx介绍 分类: Nginx 服务器搭建 2015-07-13 10:50 19人阅读 评论(0) 收藏

    海量请求,高性能服务器. 对比Apache, Apache:稳定,开源,跨平台,重量级,不支持高度并发的web服务器. 由此,出现了Lighttpd与Nignx:轻量级,高性能. 发音:engine ...

  8. oracle常用数据类型

    oracle中常用数据类型分为三大类:

  9. System Operations on AWS - Lab 5W - Managing Resources (Windows)

    登陆到CommandHost实例,通过AWS CLI来管理各个资源 1. 通过Tags来管理资源 1.1 登陆到CommandHost实例 1.2 找出development实例 1.2.1 打开Po ...

  10. System Operations on AWS - Lab 1W - Creating EC2 (Windows)

    1. 创建CommandHost实例,登录到CommandHost,通过AWS CLI创建WebServer实例. 1.1 为CommandHost实例创建一个IAM角色 1.2 创建CommandH ...