日本搞逼视频_黄色一级片免费在线观看_色99久久_性明星video另类hd_欧美77_综合在线视频

國內(nèi)最全IT社區(qū)平臺 聯(lián)系我們 | 收藏本站
阿里云優(yōu)惠2
您當前位置:首頁 > php開源 > 綜合技術(shù) > 深入理解Android之Java Security第一部分

深入理解Android之Java Security第一部分

來源:程序員人生   發(fā)布時間:2015-04-11 09:10:51 閱讀次數(shù):11577次

深入理解Android之Java Security(第1部份)

從事Android工作4年以來,只有前1年不到的時間是用C++在開發(fā)東西(主要是開發(fā)DLNA組件,目前我已將它們?nèi)块_源,參考http://blog.csdn.net/innost/article/details/40216763),后面的工作幾近都在用Java。自以為Java相干的東西都見過了,可前段時間有個朋友給我花了1個多小時講授他們某套系統(tǒng)的安全部系結(jié)構(gòu),其中觸及到很多專業(yè)術(shù)語,比如Message Digest(消息摘要)、Digital Signature(數(shù)字簽名)、KeyStore(恕我不知道翻譯成甚么好,還是用英文原稱吧)、CA(Certificate Authority)等。我當時腦袋就大了,尼瑪弄Java這么久,歷來沒接觸過啊。為此,我特地到AndroidFramework代碼中查詢了下,Android平臺里與之相干的東西還有1個KeyChain。

原來,上述內(nèi)容都屬于Java世界中1個早已存在的知識模塊,那就是JavaSecurity。Java Security包括很多知識點,常見的有MD5,DigitalSignature等,而Android在Java Seurity以外,拓展了1個android.security包,此包中就提供了KeyChain。

本文將介紹Java Security相干的基礎(chǔ)知識,然后介紹下Android平臺上與之相干的使用處景。

實際上,在1些金融,銀行,電子支付方面的利用程序中,JavaSecurity使用的地方非常多。

代碼路徑:

  • Security.java:libcore/lunl/src/main/java/java/security/
  • TrustedCertificateStore.java:libcore /crypto/src/main/java/org/conscrypt/

本文例子:

https://code.csdn.net/Innost/androidsecuritydemo  目前已公然。

1  Java Security背景知識

Java Security實際上是Java平臺中1個比較獨立的模塊。除軟件實現(xiàn)上內(nèi)容外,它實際上對應(yīng)了1系列的規(guī)范。從Java2開始,Java Security包括主要3個重要的規(guī)范:

  • JavaCryptography Extension(簡寫為JCE),JCE所包括的內(nèi)容有加解密,密鑰交換,消息摘要(Message Digest,比如MD5等),密鑰管理等。本文所觸及的大部份內(nèi)容都屬于JCE的范疇。
  • JavaSecure Socket Extension(簡寫為JSSE),JSSE所包括的內(nèi)容就是Java層的SSL/TLS。簡單點說,使用JSSE就能夠創(chuàng)建SSL/TLS socket了。
  • JavaAuthentication and Authorization Service(簡寫為JAAS),JSSA和認證/授權(quán)有關(guān)。這部份內(nèi)容在客戶端接觸得會比較少1點,所以本文不擬討論它。

在上述3個子模塊或規(guī)范中,JCE是JavaSecurity的大頭,其他兩個子模塊JSSE和JAAS都依賴于它,比如SSL/TLS在工作進程中需要使用密鑰對數(shù)據(jù)進行加解密,那末密鑰的創(chuàng)建和使用就依托JCE子模塊了。

另外,既然和安全相干,那末對安全敏感的相干部門或政府肯定會有所干涉。Java是在美國被發(fā)明的,所以美國政府對Java Security方面的出口(比如哪些模塊,哪些功能能給其他國家使用)有相干的限制。例如,不允許出口的JCE(從軟件實現(xiàn)上看,可能就是從Java官網(wǎng)上下載到的幾個Jar包文件)支持1些高級的加解密功能(比如在密鑰長度等方面有所限制)。

注意,Java Security包括的內(nèi)容非常多,而本文將重點關(guān)注Java SecurityAPI與其使用方法方面的知識。對Java Security其他細節(jié)感興趣的同學(xué)可在瀏覽完本文后,再瀏覽參考文獻[1]。

 

1.1  JCE介紹

1.1.1  JCE設(shè)計架構(gòu)介紹

介紹JCE之前,先來說解下JCE的設(shè)計架構(gòu)。JCE在設(shè)計時重點關(guān)注兩個問題:

  • 其功能具體實現(xiàn)的獨立性和可互操作性。
  • 使用算法的獨立性和可擴大性。

對獨立性而言,1個最通用的做法就是把定義和實現(xiàn)通過抽象類或基類的方式進行解耦合。在JCE中:

  • 它首先把功能組合成1個1個的Service(也稱作Engine)。比如,對應(yīng)“加解密”的API組合成CipherService,對應(yīng)“消息摘要”的API組合成MessageDigest Service,對應(yīng)“簽名”的API組合成SignatureService。JCE為這些Service都定義了1個諸如XXXSpi的抽象類。其中,SPI是Service Provider Interface的縮寫。
  • 上述SPI的具體實現(xiàn)則由不同的Provider來提供。比如JDK會提供1組默許的實現(xiàn)(固然,這些實現(xiàn)之前是由Sun公司,現(xiàn)在由Oracle提供。在這個時候,前面提到的政府管制就可以插1腳了)。注意,Provider可以提供1組Service的實現(xiàn),也能夠提供單個Service的實現(xiàn)。

注意,可互操作性是指Provider A實現(xiàn)的MD5值,能被Provider B辨認。明顯,這個要求是公道的。

圖1所示為JCE中1些類的定義:


圖1  JCE中1些類的定義

圖1展現(xiàn)了JCE中的1些類定義。大家先關(guān)注左下角的Provider和Security類:

  • Security是java.security包的主要管理類。通過它可向JCE框架注冊不同的Provider。
  • Android平臺上,每個利用程序在啟動的時候都會默許注冊1個類型為AndroidKeyStoreProvider的對象。

注意,由于歷史緣由,JCE的Service分散定義在好些個Package中:

  • java.security:此Package包括最多的Service定義。
  • javax.crypto:此package包括加解密相干的Service定義。

上述這兩個package都屬于JCE的內(nèi)容。從使用者的角度來看,其實不太需要關(guān)注它們到底定義在哪一個Package中(代碼中通過1句import xxx就能夠把對應(yīng)的包引入,后續(xù)編寫代碼時候,直接使用相干類就行了)。

BTW,個人感覺Java類定義非常多,而且有些類和它們所在包的關(guān)系仿佛有些混亂。

 

(1)  Android平臺中Provider的注冊

前面已說過,JCE框架對使用者提供的是基礎(chǔ)類(抽象類或接口類),而具體實現(xiàn)需要有地方注冊到JCE框架中。所以,我們來看看Android平臺中,JCE框架都注冊了哪些Provider:

[-->Security.java]

static {

   boolean loaded = false;

   try {

       //從資源文件里搜索是不是有security.properties定義,Android平臺是沒有這個文件的

      InputStreamconfigStream =

         Security.class.getResourceAsStream("security.properties");

       InputStream input = newBufferedInputStream(configStream);

       secprops.load(input);

       loaded = true;

       configStream.close();

        }......

     if (!loaded) {//注冊默許的Provider

        registerDefaultProviders();

     }

      ......

    }

 

   private static void registerDefaultProviders() {

     /*

    JCE對Provider的管理非常簡單,就是將Provider類名和對應(yīng)的優(yōu)先級存在屬性列表里

    比以下面的:OpenSSLProvider,它對應(yīng)的優(yōu)先級是1.

     優(yōu)先級是甚么意思呢?前面說過,不同的Provider可以實現(xiàn)同1個功能集合,比如都實現(xiàn)

     MessageDigestSpi。那末用戶在創(chuàng)建MessageDigest的實例時,如果沒有指明Provider名,

     JCE默許從第1個(依照優(yōu)先級,由1到n)Provider開始搜索,直到找到第1個實現(xiàn)了

     MessageDigestSpi的Provider(比如Provider X)為止。然后,MessageDigest的實例

      就會由Provider X創(chuàng)建。圖2展現(xiàn)了1個例子

    */

     secprops.put("security.provider.1",

           "com.android.org.conscrypt.OpenSSLProvider");

     secprops.put("security.provider.2",

            "org.apache.harmony.security.provider.cert.DRLCertFactory");

    secprops.put("security.provider.3",

       "com.android.org.bouncycastle.jce.provider.BouncyCastleProvider");

    secprops.put("security.provider.4",

        "org.apache.harmony.security.provider.crypto.CryptoProvider");

      //JSSE有關(guān)

      secprops.put("security.provider.5",

        "com.android.org.conscrypt.JSSEProvider");

 }

圖2展現(xiàn)了Provider優(yōu)先級使用的例子:


圖2  Provider優(yōu)先級示例

圖2中:

  • 左側(cè)的Application要使用MD5算法來創(chuàng)建1個MessageDigest實例。而左下角有3個Provider(A、B、C)。其中B和C支持MD5算法。所以JCE會使用第1個實現(xiàn)MD5算法的Provider(即Provider B)來創(chuàng)建MessageDigest實例。
  • 右側(cè)的Application也要使用MD5算法來創(chuàng)建MD實例。但是它在參數(shù)中指明了Provider的名字(“ProviderC”),所以JCE就會直接使用ProviderC來創(chuàng)建這個MD實例。

注意,圖2中的SHA⑴/256和MD5都是MessageDigest的1種算法,本文后面會介紹它們。

(2) AndroidKeyStoreProvider

Android平臺中,每一個利用程序啟動時都會注冊1個類型為“AndroidKeyStoreProvider”的對象。這是在ActivityThread中完成的,代碼以下所示:

[-->ActivityThread.java::main]

public static void main(String[] args) {

   ......

  Security.addProvider(new AndroidKeyStoreProvider());

  ......

}

來看看AndroidKeyStoreProvider是甚么,代碼以下所示:

[-->AndroidKeyStoreProvider::AndroidKeyStoreProvider]

public class AndroidKeyStoreProvider extends Provider {

  public static final StringPROVIDER_NAME = "AndroidKeyStore";

  publicAndroidKeyStoreProvider() {

    super(PROVIDER_NAME, 1.0,"Android KeyStore security provider");

    put("KeyStore." + AndroidKeyStore.NAME,

          AndroidKeyStore.class.getName());

    put("KeyPairGenerator.RSA",AndroidKeyPairGenerator.class.getName());

  }

}

AndroidKeyStoreProvider很簡單,但是看上去還是不明白它是干甚么的?其實,這個問題的更深層次的問題是:Provider是干甚么的?

  • Provider從Properties類派生。Properties本質(zhì)上是1個屬性列表,也就是它保存了1串的屬性名和對應(yīng)的屬性值。
  • 從圖2的例子可知,利用程序只說要創(chuàng)建MD5的MessageDigest實例。在代碼中,“MD5”是1個字符串,而MessageDigest實例肯定是由某個類創(chuàng)建的(假定這個類名叫com.md5.test)。那末,這個“MD5”字符串就是1個Key,對應(yīng)的屬性值就是這個類的類名(“com.md5.test”)。JCE根據(jù)屬性key,找到屬性value,然后創(chuàng)建這個類的實例就完成了工作!

固然,Provider的內(nèi)容和功能比這要復(fù)雜,不過我們對Provider的實現(xiàn)沒甚么興趣,大家只要知道它存儲了1系列的屬性key和value就能夠了。JCE會根據(jù)情況去查詢這些key和對應(yīng)的value。

(3)  實例介紹

來個例子,看看Android系統(tǒng)上都有哪些Provider:

[-->DemoActivity.java::testProvider]

void testProvider(){

   e(TAG, "***Begin TestProviders***");

   //獲得系統(tǒng)所有注冊的Provider

   Provider[] providers = Security.getProviders();

   for(Providerprovider:providers){

      //輸出Provider名

      e(TAG,"Provider:" + provider+" info:");

      //前面說了,provider其實就是包括了1組key/value值。下面將打印每一個Provider的

      //這些信息

      Set<Entry<Object,Object>>allKeyAndValues = provider.entrySet();

     Iterator<Entry<Object, Object>> iterator =allKeyAndValues.iterator();

      while(iterator.hasNext()){

        Entry<Object,Object> oneKeyAndValue =iterator.next();

        Object key = oneKeyAndValue.getKey();

        Object value =oneKeyAndValue.getValue();

        //打印Key的類型和值

       e(TAG,"===>" + "Keytype="+key.getClass().getSimpleName()+"

                           Key="+key.toString());

        //打印Value的類型和值

      e(TAG,"===>" + "Valuetype="+value.getClass().getSimpleName()+"

                           Value="+value.toString());

        }

     }

     e(TAG, "***End TestProviders*** ");

 }

在控制臺中,通過adb logcat | grep ASDemo就能夠顯示testProvider的輸出信息了,如圖3所示:


圖3  testProvider輸出示例

圖3打出了AndroidOpenSSLprovider的信息:

  • 其中Key和Value的類型都是String。
  • Key的值其實都是JCE中1些Service或算法的名稱或別名。此處先不討論這些細節(jié),以后碰到再說。

了解完JCE框架后,我們分別來介紹JCE中的1些重要Service。

1.1.2  Key知識介紹

談到安全,大家第1想到的就是密鑰,即Key。那末大家再仔細想一想下面這兩個問題:

  • Key從何而來?即代碼中怎樣創(chuàng)建Key。
  • Key怎樣傳遞給外部使用者?外部使用者多是1個開發(fā)者,這時候候就不能把代碼中的1個對象通過email發(fā)給他了,而是要把Key的書面表達情勢(參考資料[1]把它叫做externalrepresentations,即外部表達情勢。我為了強調(diào)這類表達情勢,把它稱為書面表達情勢。便可有把Key寫到文檔里,發(fā)給其他人)發(fā)給人家。

圖4解釋了上述問題:


圖4  Key示意

圖4中:

  • Key怎樣創(chuàng)建?在JCE中是通過Generator類創(chuàng)建的,這時候候在代碼中得到的是1個Key實例對象。
  • Key怎樣傳遞?這就觸及到如何書面表達Key了,最最經(jīng)常使用的方式就是把它表示成16進制(比如圖4中下部Encoded Key Data“0AF34C4E56...”)。或,由于Key產(chǎn)生是基于算法的,這時候候就能夠把參與計算的關(guān)鍵變量的值弄出來。比如圖4右上角的“Param P=3,ParamQ=4”。所以,Key的書面表達情勢有兩種,1種是16進制密鑰數(shù)據(jù),1種是基于算法的關(guān)鍵變量(這類方式叫KeySpecification)。
  • 爾后,我們可以把16進制或關(guān)鍵變量發(fā)給對方。對方拿到Key的書面表達式后,下1步要做的就是還原出代碼中的key對象。這時候候要用到的就是KeyFactory了。所以,KeyFactory的輸入是Key的2進制數(shù)據(jù)或KeySpecification,輸出就是Key對象。

在安全領(lǐng)域中,Key分為兩種:

  • 對稱Key:即加密和解密用得是同1個Key。JCE中,對稱key的創(chuàng)建由KeyGenerator類來完成。
  • 非對稱Key:即加密和解密用得是兩個Key。這兩個Key構(gòu)成1個Key對(KeyPair)。其中1個Key叫公鑰(PublicKey),另外1個Key叫私鑰(PrivateKey)。公鑰加密的數(shù)據(jù)只能用私鑰解密,而私鑰加密的數(shù)據(jù)只能用公鑰解密。私鑰1般自己保存,而公鑰是需要發(fā)給合作方的。(此處我們還不討論公鑰和私鑰的使用處景,僅限介紹公鑰和私鑰的概念)。JCE中,非對稱Key的創(chuàng)建由KeyPairGenerator類來完成。

圖5所示為JCE中Key相干的類和繼承關(guān)系。


圖5  JCE Key相干類

圖5中:

  • PublicKey,PrivateKey和SecretKey都派生自Key接口。所以,這3個類也是接口類,而且沒有定義新的接口。
  • DSAPublicKey和RSAPublicKey也派生自PublicKey接口。DSA和RSA是兩種不同的算法。

(1)  Key實例介紹

先來看對稱key的創(chuàng)建和導(dǎo)入(也就是把Key的書面表達導(dǎo)入到程序中并生成Key對象)

[-->DemoActivity.java::testKey]

{//對稱key即SecretKey創(chuàng)建和導(dǎo)入

     //假定雙方約定使用DES算法來生成對稱密鑰

     e(TAG,"==>secret key: generated it using DES");

     KeyGeneratorkeyGenerator = KeyGenerator.getInstance("DES");

     //設(shè)置密鑰長度。注意,每種算法所支持的密鑰長度都是不1樣的。DES只支持64位長度密鑰

     //(或許是算法本身的限制,或是不同Provider的限制,或是政府管制的限制

     keyGenerator.init(64);

     //生成SecretKey對象,即創(chuàng)建1個對稱密鑰

     SecretKey secretKey = keyGenerator.generateKey();

     //獲得2進制的書面表達

     byte[] keyData =secretKey.getEncoded();

     //平常使用時,1般會把上面的2進制數(shù)組通過Base64編碼轉(zhuǎn)換成字符串,然后發(fā)給使用者

     String keyInBase64 =Base64.encodeToString(keyData,Base64.DEFAULT);

     e(TAG,"==>secret key: encrpted data ="+ bytesToHexString(keyData));

     e(TAG,"==>secrety key:base64code=" + keyInBase64);

     e(TAG,"==>secrety key:alg=" + secretKey.getAlgorithm());

    

    //假定對方收到了base64編碼后的密鑰,首先要得到其2進制表達式

   byte[] receivedKeyData =Base64.decode(keyInBase64,Base64.DEFAULT);

   //用2進制數(shù)組構(gòu)造KeySpec對象。對稱key使用SecretKeySpec類

   SecretKeySpec keySpec =new SecretKeySpec(receivedKeyData,”DES”);

   //創(chuàng)建對稱Key導(dǎo)入用的SecretKeyFactory

   SecretKeyFactorysecretKeyFactory = SecretKeyFactory.getInstance(”DES”);

   //根據(jù)KeySpec還原Key對象,即把key的書面表達式轉(zhuǎn)換成了Key對象

   SecretKey receivedKeyObject = secretKeyFactory.generateSecret(keySpec);

   byte[]encodedReceivedKeyData = receivedKeyObject.getEncoded();

   e(TAG,"==>secret key: received key encoded data ="

                                +bytesToHexString(encodedReceivedKeyData));

如果1切正常的話,紅色代碼和綠色代碼打印出的2進制表示應(yīng)當完全1樣。此測試的結(jié)果如圖6所示:


圖6  SecretKey測試結(jié)果

此處有幾點說明:

  • 對稱key的創(chuàng)建有不同的算法支持,根據(jù)參考資料[1],1般有Blowfish, DES, DESede,HmacMD5,HmacSHA1,PBEWithMD5AndDES, and PBEWithMD5AndTripleDES這些算法。但是Android平臺,乃至不同手機是不是都支持這些算法,則需要在testProvider那個例子去查詢。
  • 另外,KeyGenerator如果支持上面的算法,但是SecretKeyFactory則不1定支持。比如ScreteKeyFactory則不支持HmacSHA1。

注意,本文會討論太多算法相干的內(nèi)容。

再來看KeyPair的用例:

[-->DemoActivity.java::KeyPair測試]

{//public/private key test

  e(TAG, "==>keypair: generated it using RSA");

  //使用RSA算法創(chuàng)建KeyPair

  KeyPairGeneratorkeyPairGenerator = KeyPairGenerator.getInstance("RSA");

  //設(shè)置密鑰長度

  keyPairGenerator.initialize(1024);

  //創(chuàng)建非對稱密鑰對,即KeyPair對象

  KeyPair keyPair =keyPairGenerator.generateKeyPair();

  //獲得密鑰對中的公鑰和私鑰對象

  PublicKey publicKey =keyPair.getPublic();

  PrivateKey privateKey =keyPair.getPrivate();

  //打印base64編碼后的公鑰和私鑰值

  e(TAG,"==>publickey:"+bytesToHexString(publicKey.getEncoded()));

  e(TAG, "==>privatekey:"+bytesToHexString(privateKey.getEncoded()));

 

  /*

   現(xiàn)在要斟酌如何把公鑰傳遞給使用者。雖然可以和對稱密鑰1樣,把2進制數(shù)組取出來,但是

   對非對稱密鑰來講,JCE不支持直接通過2進制數(shù)組來還原KeySpec(多是算法不支持)。

   那該怎樣辦呢?前面曾說了,除直接還原2進制數(shù)組外,還可以通過具體算法的參數(shù)來還原

   RSA非對稱密鑰就得使用這類方法:

   1 首先我們要獲得RSA公鑰的KeySpec。

  */

  //獲得RSAPublicKeySpec的class對象

  Class spec = Class.forName("java.security.spec.RSAPublicKeySpec");

   //創(chuàng)建KeyFactory,并獲得RSAPublicKeySpec

  KeyFactory keyFactory = KeyFactory.getInstance("RSA");

  RSAPublicKeySpecrsaPublicKeySpec =

            (RSAPublicKeySpec)keyFactory.getKeySpec(publicKey, spec);

  //對RSA算法來講,只要獲得modulusexponent這兩個RSA算法特定的參數(shù)就能夠了

  BigInteger modulus =rsaPublicKeySpec.getModulus();

  BigInteger exponent =rsaPublicKeySpec.getPublicExponent();

  //把這兩個參數(shù)轉(zhuǎn)換成Base64編碼,然后發(fā)送給對方

  e(TAG,"==>rsa pubkey spec:modulus="+

             bytesToHexString(modulus.toByteArray()));

  e(TAG,"==>rsa pubkey spec:exponent="+

             bytesToHexString(exponent.toByteArray()));

 

  //假定接收方收到了代表modulus和exponent的base64字符串并得到了它們的2進制表達式

  byte[] modulusByteArry =modulus.toByteArray();

  byte[] exponentByteArry =exponent.toByteArray();

  //由接收到的參數(shù)構(gòu)造RSAPublicKeySpec對象

  RSAPublicKeySpecreceivedKeySpec = new RSAPublicKeySpec(

                    newBigInteger(modulusByteArry),

                    new BigInteger(exponentByteArry));

  //根據(jù)RSAPublicKeySpec對象獲得公鑰對象

  KeyFactoryreceivedKeyFactory = keyFactory.getInstance("RSA");

  PublicKey receivedPublicKey =

                 receivedKeyFactory.generatePublic(receivedKeySpec);

  e(TAG, "==>received pubkey:"+

                   bytesToHexString(receivedPublicKey.getEncoded()));

}

如果1切正常的話,上述代碼中紅色和黑色代碼段將輸出完全1樣的公鑰2進制數(shù)據(jù)。如圖7所示:


圖7  KeyPair測試示意圖

在Android平臺的JCE中,非對稱Key的經(jīng)常使用算法有“RSA”、“DSA”、“Diffie?Hellman”、“Elliptic Curve (EC)”等。

(2)  Key知識小結(jié)

我自己在學(xué)習(xí)Key的時候,最迷惑的就是前面提到的兩個問題:

Key是甚么?雖然“密鑰”這個詞常常讓我聯(lián)想到實際生活中的鑰匙,但是在學(xué)習(xí)JavaSecurity之前,我1直不知道在代碼中(或編程時),它究竟是個甚么玩意。并且,它到底怎樣創(chuàng)建。

創(chuàng)建Key以后,我怎樣把它傳遞給其他人。就好比鑰匙1樣,你總得給個實物給人家吧?

現(xiàn)在來看這兩個問題的總結(jié)性回答:):

  • JCE中,Key根據(jù)加密方法的不同,分為對稱Key和非對稱Key兩大類。其中對稱Key由類SecretKey表達,而非對稱Key常常是公鑰和私鑰構(gòu)成1個密鑰對。在程序里,他們的類型分別是PublicKey、PrivateKey和KeyPair。
  • SecretKey和KeyPair都有對應(yīng)的Generator類來創(chuàng)建。其中,創(chuàng)建對稱Key的是KeyGenerator,創(chuàng)建KeyPair的是KeyPairGenerator。1方創(chuàng)建Key后,怎樣把密鑰信息傳遞給其他人呢?這時候就需要用到Key的外部表現(xiàn)情勢了(我把它叫做書面表達情勢)。
  • Key的書面表達式有兩種,1種是直接把它的2進制數(shù)組弄出來,然后編碼成base64發(fā)給對方。對方從這個base64編碼字符串中得到2進制數(shù)組。這個2進制數(shù)組叫KeyEncoded Data。怎樣把它轉(zhuǎn)換成代碼中的Key實例呢?對對稱Key來講,先用這個2進制數(shù)組構(gòu)造1個SecretKeySpec,然后再用SecretKeyFactory構(gòu)造出終究的SecretKey對象。
  • Key的另外1種表示式就是利用創(chuàng)建Key的算法。這個主要針對非對稱Key。Key創(chuàng)建時,總是需要依賴1些特定的算法,而這些算法也會有1些參數(shù)。類似于學(xué)數(shù)學(xué)時,算法對應(yīng)于1個公式,我們只要把參數(shù)值帶入進去就可以得到結(jié)果1樣。所以,在這類情況下,我們只要把參數(shù)保存起來,然后傳遞給對方可以了。對方拿到這些個參數(shù),再構(gòu)造出對應(yīng)算法所需要的KeySpec對象,最后由KeyPairFactory創(chuàng)建終究的Key對象。

不理解上述內(nèi)容的同學(xué),請把實例代碼再仔細看看!

 

1.1.3  Certificates知識介紹

JCE中,Certificates(是復(fù)數(shù)喔!)是證書之意。“證書”也是1個平常生活中經(jīng)常使用的詞,但是在JCE中,或說在Java Security中,它有甚么用呢?

這個問題的答案還是和Key的傳遞有關(guān)系。前面例子中我們說,創(chuàng)建密鑰的人1般會把Key的書面表達情勢轉(zhuǎn)換成Base64編碼后的字符串發(fā)給使用者。使用者再解碼,然后還原Key就能夠用了。

上面這個流程本身沒有甚么隱患,但是,是否是隨便1個人(1個組織,1個機構(gòu)等等等等)給你發(fā)1個key,你就敢用呢?簡單點說,你怎樣判斷是不是該信任給你發(fā)Key的某個人或某個機構(gòu)呢?

好吧,這就好比現(xiàn)實生活中有個人說自己是警察,那你肯定得要他取出警官證或甚么別的東西來證明他是警察。這個警官證的作用就是證書的作用。

1般而言,我們會把Key的2進制表達式放到證書里,證書本身再填上其他信息(比如此證書是誰簽發(fā)的,甚么時候簽發(fā)的,有效期多久,證書的數(shù)字簽名等等)。

初看起來,好像證書比直接發(fā)base64字符串要正規(guī)點,1方面它包括了證書簽發(fā)者的信息,而且還有數(shù)字簽名以避免內(nèi)容被篡改。

但是,證書解決了信任的問題嗎?很明顯是沒有的。由于證書是誰都可以制作的。既然不是人人都可以相信,那末,也不是隨意甚么證書都可以被信任。

怎樣辦?先來看現(xiàn)實生活中是怎樣解決信任問題的。

現(xiàn)實生活中也有很多證書,大到房產(chǎn)證、身份證,小到離職證明、介紹信。對方怎樣判斷你拿的這些證是真實有效的呢?

對頭,看證書是誰/或哪一個機構(gòu)的“手墨”!比如,結(jié)婚證首先要看是否是民政局的章。那....民政局是不是應(yīng)當被信任呢???

好吧。關(guān)于民政局是不是應(yīng)當被信任的這個問題在技術(shù)上基本無解,它是1個死循環(huán)。由于,即便能找到另外1個機構(gòu)證明民政局合法有效,但這個問題仍然會順流而上,說民政局該被信任的那個機構(gòu)其本身是不是能被信任呢?....此問題終究會沒完沒了的問下去。

那怎樣辦?沒甚么好辦法。只要大家公認民政局能被信任,就能夠了。

同理,對證書的是不是可信任問題而言:

  • 首先,在全球范圍內(nèi)(或是1個國家,1個地區(qū))設(shè)置1些頂級證書簽發(fā)機構(gòu),凡是由這些證書簽發(fā)機構(gòu)(CertificateAuthorities)簽發(fā)的證書,我們要無條件的信任(不斟酌其他捏造等因素,證書是不是被篡改可通過數(shù)字簽名來判斷)。就和民政局似的,不信民政局還信誰?:)。
  • 這么多證書要發(fā),頂級CA肯定忙不過來,所以還可以設(shè)立各種級別的CA,比如北京市的民政局弄1個CA,湖南省的公安廳弄1個CA。這類級別的CA是不是該無條件信任呢?不1定。看你對它的了解。anyway,這個級別的CA可以把自己拿到頂級CA那去認個證。比方說,湖南省公安廳發(fā)了1個證書,它可以到頂級CA那去蓋個章。由于頂級CA是無條件信任的,所以湖南省公安廳這個證書可以被信任。
  • 公司A要發(fā)證書給客戶使用,最好是先拿到上1級或相干領(lǐng)域的CA(不1定是頂級CA)那去蓋個章。最后,公司A把蓋了章的證書a發(fā)給客戶使用就能夠了。

客戶拿到證書a后,首先要檢查下:

  • 客戶拿到證書a后,發(fā)現(xiàn)是某個CA簽發(fā)的。如果是頂級CA簽發(fā)的,那好辦,直接信任。如果不是頂級CA簽發(fā)的。客戶再去查看這個發(fā)證的CA能不能被信任,溯流而上,直到跟蹤到頂級CA為止。所以,證書,常常不是1個證書的事情,而是1個證書鏈的事情!
  • 另外,如果客戶本身就信任公司A,那其實公司A也不需要去找CA認證,直接把證書a給客戶就能夠了。固然,這個時候的證書a就不需要CA的章了。

......唧唧歪歪半天,其實關(guān)于證書的核心問題就1個:

證書背后常常是1個證書鏈。

  • 大家不要小視這個問題。證書鏈常常會把問題弄復(fù)雜。比如甲方有CA A簽發(fā)的證書,而乙方有CA B簽發(fā)的證書。那末甲乙雙方要相互信任的話,得把甲乙雙方證書鏈上的證書都弄過來校驗1遍,直到頂級CA為止。固然,甲乙證書鏈的頂級CA可能還不是同1個。

.......

為了方便,系統(tǒng)(PC,Android,乃至閱讀器)等都會把1些頂級CA(也叫Root CA,即根CA)的證書默許集成到系統(tǒng)里。這些RootCA用作自己身份證明的證書(包括該CA的公鑰等信息)叫根證書。根證書理論上是需要被信任的。以Android為例,它在libcore/luni/src/main/files/cacerts下放了150多個根證書(以Android 4.4為例),如圖8所示:


圖8  Android自帶的根證書文件

我們隨意打開1個根證書文件看看,以下所示:

[某證書文件的內(nèi)容,用記事本打開便可]

-----BEGIN CERTIFICATE-----

MIID5TCCAs2gAwIBAgIEOeSXnjANBgkqhkiG9w0BAQUFADCBgjELMAkGA1UEBhMC

VVMxFDASBgNVBAoTC1dlbGxzIEZhcmdvMSwwKgYDVQQLEyNXZWxscyBGYXJnbyBD

ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEvMC0GA1UEAxMmV2VsbHMgRmFyZ28gUm9v

dCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDAxMDExMTY0MTI4WhcNMjEwMTE0

MTY0MTI4WjCBgjELMAkGA1UEBhMCVVMxFDASBgNVBAoTC1dlbGxzIEZhcmdvMSww

KgYDVQQLEyNXZWxscyBGYXJnbyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEvMC0G

A1UEAxMmV2VsbHMgRmFyZ28gUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEi

MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDVqDM7Jvk0/82bfuUER84A4n13

5zHCLielTWi5MbqNQ1mXx3Oqfz1cQJ4F5aHiidlMuD+b+Qy0yGIZLEWukR5zcUHE

SxP9cMIlrCL1dQu3U+SlK93OvRw6esP3E48mVJwWa2uv+9iWsWCaSOAlIiR5NM4O

JgALTqv9i86C1y8IcGjBqAr5dE8Hq6T54oN+J3N0Prj5OEL8pahbSCOz6+MlsoCu

ltQKnMJ4msZoGK43YjdeUXWoWGPAUe5AeH6orxqg4bB4nVCMe+ez/I4jsNtlAHCE

AQgAFG5Uhpq6zPk3EPbg3oQtnaSFN9OH4xXQwReQfhkhahKpdv0SAulPIV4XAgMB

AAGjYTBfMA8GA1UdEwEB/wQFMAMBAf8wTAYDVR0gBEUwQzBBBgtghkgBhvt7hwcB

CzAyMDAGCCsGAQUFBwIBFiRodHRwOi8vd3d3LndlbGxzZmFyZ28uY29tL2NlcnRw

b2xpY3kwDQYJKoZIhvcNAQEFBQADggEBANIn3ZwKdyu7IvICtUpKkfnRLb7kuxpo

7w6kAOnu5+/u9vnldKTC2FJYxHT7zmu1Oyl5GFrvm+0fazbuSCUlFLZWohDo7qd/

0D+j0MNdJu4HzMPBJCGHHt8qElNvQRbn7a6U+oxy+hNH8Dx+rn0ROhPs7fpvcmR7

nX1/Jv16+yWt6j4pf0zjAFcysLPp7VMX2YuyFA4w6OXVE8Zkr8QA1dhYJPz1j+zx

x32l2w8n0cbyQIjmH/ZhqPRCyLk306m+LFZ4wnKbWV01QIroTmMatukgalHizqSQ

33ZwmVxwQ023tqcZZE6St8WRPH9IFmV7Fv3L/PvZ1dZPIWU7Sn9Ho/s=

-----END CERTIFICATE-----

Certificate:  #下面是證書的明文內(nèi)容

    Data:

        Version: 3 (0x2)

        Serial Number:971282334 (0x39e4979e)

    Signature Algorithm: sha1WithRSAEncryption

        Issuer: C=US, O=Wells Fargo, OU=Wells Fargo CertificationAuthority, CN=Wells Fargo Root Certificate Authority

        Validity

            Not Before: Oct11 16:41:28 2000 GMT

            Not After : Jan14 16:41:28 2021 GMT

        Subject: C=US, O=Wells Fargo, OU=Wells Fargo CertificationAuthority, CN=Wells Fargo Root Certificate Authority

        Subject Public Key Info:#Public KeyKeySpec表達式

            Public Key Algorithm: rsaEncryption  #PublicKey的算法

                Public-Key: (2048 bit)

                Modulus:

                   00:d5:a8:33:3b:26:f9:34:ff:cd:9b:7e:e5:04:47:

                   ce:00:e2:7d:77:e7:31:c2:2e:27:a5:4d:68:b9:31:

                   ba:8d:43:59:97:c7:73:aa:7f:3d:5c:40:9e:05:e5:

                    a1:e2:89:d9:4c:b8:3f:9b:f9:0c:b4:c8:62:19:2c:

                   45:ae:91:1e:73:71:41:c4:4b:13:fd:70:c2:25:ac:

                   22:f5:75:0b:b7:53:e4:a5:2b:dd:ce:bd:1c:3a:7a:

                   c3:f7:13:8f:26:54:9c:16:6b:6b:af:fb:d8:96:b1:

                    60:9a:48:e0:25:22:24:79:34:ce:0e:26:00:0b:4e:

                   ab:fd:8b:ce:82:d7:2f:08:70:68:c1:a8:0a:f9:74:

                   4f:07:ab:a4:f9:e2:83:7e:27:73:74:3e:b8:f9:38:

                   42:fc:a5:a8:5b:48:23:b3:eb:e3:25:b2:80:ae:96:

                    d4:0a:9c:c2:78:9a:c6:68:18:ae:37:62:37:5e:51:

                   75:a8:58:63:c0:51:ee:40:78:7e:a8:af:1a:a0:e1:

                   b0:78:9d:50:8c:7b:e7:b3:fc:8e:23:b0:db:65:00:

                   70:84:01:08:00:14:6e:54:86:9a:ba:cc:f9:37:10:

                   f6:e0:de:84:2d:9d:a4:85:37:d3:87:e3:15:d0:c1:

                   17:90:7e:19:21:6a:12:a9:76:fd:12:02:e9:4f:21:

                    5e:17

                Exponent: 65537 (0x10001)

        X509v3 extensions:

            X509v3 BasicConstraints: critical

                CA:TRUE

            X509v3Certificate Policies:

                Policy:2.16.840.1.114171.903.1.11

                  CPS:http://www.wellsfargo.com/certpolicy

 

    Signature Algorithm: sha1WithRSAEncryption  #數(shù)字簽名,以后再講

        d2:27:dd:9c:0a:77:2b:bb:22:f2:02:b5:4a:4a:91:f9:d1:2d:

        be:e4:bb:1a:68:ef:0e:a4:00:e9:ee:e7:ef:ee:f6:f9:e5:74:

        a4:c2:d8:52:58:c4:74:fb:ce:6b:b5:3b:29:79:18:5a:ef:9b:

        ed:1f:6b:36:ee:48:25:25:14:b6:56:a2:10:e8:ee:a7:7f:d0:

        3f:a3:d0:c3:5d:26:ee:07:cc:c3:c1:24:21:87:1e:df:2a:12:

        53:6f:41:16:e7:ed:ae:94:fa:8c:72:fa:13:47:f0:3c:7e:ae:

        7d:11:3a:13:ec:ed:fa:6f:72:64:7b:9d:7d:7f:26:fd:7a:fb:

        25:ad:ea:3e:29:7f:4c:e3:00:57:32:b0:b3:e9:ed:53:17:d9:

        8b:b2:14:0e:30:e8:e5:d5:13:c6:64:af:c4:00:d5:d8:58:24:

        fc:f5:8f:ec:f1:c7:7d:a5:db:0f:27:d1:c6:f2:40:88:e6:1f:

        f6:61:a8:f4:42:c8:b9:37:d3:a9:be:2c:56:78:c2:72:9b:59:

        5d:35:40:8a:e8:4e:63:1a:b6:e9:20:6a:51:e2:ce:a4:90:df:

        76:70:99:5c:70:43:4d:b7:b6:a7:19:64:4e:92:b7:c5:91:3c:

        7f:48:16:65:7b:16:fd:cb:fc:fb:d9:d5:d6:4f:21:65:3b:4a:

         7f:47:a3:fb

SHA1 Fingerprint=93:E6:AB:22:03:03:B5:23:28:DC:DA:56:9E:BA:E4:D1:D1:CC:FB:65

關(guān)于證書文件,還有1些容易混淆的事情要交代:

  • 前面講過,證書有很多格式,但是目前通用格式為X.509格式。在上面的證書文件中,從Certificate這1行開始到文件最后,都是符合X.509格式的。那文件前面的“-----BEGINCERTIFICATE-----”到“-----END CERTIFICATE-----”是些甚么?
  • X.509是證書的格式,但是證書和我們看到的文件還是有1些差異。證書需要封裝在文件里。不同系統(tǒng)支持不同的證書文件,每種證書文件,所要求包括的具體的X.509證書內(nèi)容也不1樣。另外,某些證書文件還能包括除X.509以外的其他有用的數(shù)據(jù)。

下面是1些常見的證書文件格式,1般用文件后綴名標示。

  • .pem(Privacy-enhanced ElectronicMail) Base64 編碼的證書,編碼信息(行將示例中X.509證書的明文內(nèi)容用Base64編碼后得到的那個字符串)放在"-----BEGIN CERTIFICATE-----" and "-----END CERTIFICATE-----"之間。所以,Android平臺里的根CA文件都是PEM證書文件。
  • .cer,.crt, .der:證書內(nèi)容為ASCII編碼,2進制格式,但也能夠和PEM1樣采取base64編碼。
  • .p7b,.p7c
    生活不易,碼農(nóng)辛苦
    如果您覺得本網(wǎng)站對您的學(xué)習(xí)有所幫助,可以手機掃描二維碼進行捐贈
    程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關(guān)閉
程序員人生
主站蜘蛛池模板: 少妇视频一区 | 国产一级片在线播放 | 一区二区三区精品视频 | 欧美日韩国产高清视频 | 不卡欧美| 求av网站| 欧美午夜一区二区三区免费大片 | 国产三级三级三级精品8ⅰ区 | 国产精品免费一区二区三区都可以 | 黄色国产| 日韩一区二区高清 | 亚洲福利网 | 久久久久久一区二区三区四区别墅 | 电影天堂网 | 亚洲国产精品福利 | 日本中文在线 | 精品久久免费 | 日本欧美久久久 | 国产a精品| 91网站入口| 国产最新在线 | 好看的黄色网址 | 国产精品一区二区不卡 | 国产亚洲二区 | 欧美精品xx| 91免费国产在线 | 欧美日韩精品电影 | 亚洲人成电影在线 | jizzjizz中国丰满熟少妇 | 91精品国产高清久久久久久久久 | 日韩精品一区二区三区四区 | 国产三级精品三级在线观看国产 | 美一级片 | 久久性生活免费视频 | 成人精品影院 | 国产午夜精品一区二区三区嫩草 | a久久| 999国产视频 | 精品国产免费一区二区三区四区 | 精品国产一区二区三区麻豆小说 | 人人爽人人爽 |