歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

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");

也能正常執行。

Copyright © Linux教程網 All Rights Reserved