java加密類型和演算法名稱,java密碼編譯演算法
項目裡有各種加密方法,但從來沒有仔細研究過。一般只是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方法,其中給了我們提示:
我們可以本地寫一個方法遍曆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");
也能正常執行。