项目里有各种加密方法,但从来没有仔细研究过。一般只是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");
也能正常执行。