小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

Android開發(fā)資料

 昵稱Q99IG 2016-07-24
        RSA是目前最有影響力的公鑰加密算法,該算法基于一個十分簡單的數(shù)論事實:將兩個大素數(shù)相乘十分容易,但那時想要對其乘積進(jìn)行因式分解卻極其困難,因此可以將乘積公開作為加密密鑰,即公鑰,而兩個大素數(shù)組合成私鑰。公鑰是可發(fā)布的供任何人使用,私鑰則為自己所有,供解密之用。

        解密者擁有私鑰,并且將由私鑰計算生成的公鑰發(fā)布給加密者。加密都使用公鑰進(jìn)行加密,并將密文發(fā)送到解密者,解密者用私鑰解密將密文解碼為明文。

        以甲要把信息發(fā)給乙為例,首先確定角色:甲為加密者,乙為解密者。首先由乙隨機(jī)確定一個KEY,稱之為密匙,將這個KEY始終保存在機(jī)器B中而不發(fā)出來;然后,由這個 KEY計算出另一個KEY,稱之為公匙。這個公鑰的特性是幾乎不可能通過它自身計算出生成它的私鑰。接下來通過網(wǎng)絡(luò)把這個公鑰傳給甲,甲收到公鑰后,利用公鑰對信息加密,并把密文通過網(wǎng)絡(luò)發(fā)送到乙,最后乙利用已知的私鑰,就對密文進(jìn)行解碼了。以上就是RSA算法的工作流程。

        算法實現(xiàn)過程為:

        1. 隨意選擇兩個大的質(zhì)數(shù)p和q,p不等于q,計算N=pq。
        2. 根據(jù)歐拉函數(shù),不大于N且與N互質(zhì)的整數(shù)個數(shù)為(p-1)(q-1)。
        3. 選擇一個整數(shù)e與(p-1)(q-1)互質(zhì),并且e小于(p-1)(q-1)。
        4. 用以下這個公式計算d:d× e ≡ 1 (mod (p-1)(q-1))。
        5. 將p和q的記錄銷毀。

        以上內(nèi)容中,(N,e)是公鑰,(N,d)是私鑰。

        下面講解RSA算法的應(yīng)用。

        RSA的公鑰和私鑰是由KeyPairGenerator生成的,獲取KeyPairGenerator的實例后還需要設(shè)置其密鑰位數(shù)。設(shè)置密鑰位數(shù)越高,加密過程越安全,一般使用1024位。如下代碼:

1KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(RSA);
2// 密鑰位數(shù)
3keyPairGen.initialize(1024);


        公鑰和私鑰可以通過KeyPairGenerator執(zhí)行g(shù)enerateKeyPair()后生成密鑰對KeyPair,通過KeyPair.getPublic()和KeyPair.getPrivate()來獲取。如下代碼:

1// 動態(tài)生成密鑰對,這是當(dāng)前最耗時的操作,一般要2s以上。
2KeyPair keyPair = keyPairGen.generateKeyPair();
3// 公鑰
4PublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
5// 私鑰
6PrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
7byte[] publicKeyData = publicKey.getEncoded();
8byte[] privateKeyData = publicKey.getEncoded();

        公鑰和私鑰都有它們自己獨特的比特編碼,可以通過getEncoded()方法獲取,返回類型為byte[]。通過byte[]可以再度將公鑰或私鑰還原出來。具體代碼如下:

01// 通過公鑰byte[]將公鑰還原,適用于RSA算法
02public static PublicKey getPublicKey(byte[] keyBytes) throws
03NoSuchAlgorithmException,InvalidKeySpecException {
04        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
05        KeyFactory keyFactory = KeyFactory.getInstance('RSA');
06        PublicKey publicKey = keyFactory.generatePublic(keySpec);
07        return publicKey;
08}
09// 通過私鑰byte[]將公鑰還原,適用于RSA算法
10public static PrivateKey getPrivateKey(byte[] keyBytes) throws
11NoSuchAlgorithmException,InvalidKeySpecException {
12        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
13        KeyFactory keyFactory = KeyFactory.getInstance('RSA');
14        PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
15        return privateKey;
16}

        在上文講到的RSA算法實現(xiàn)過程中提到(N,e)是公鑰,(N,d)是私鑰。既然已經(jīng)獲取到了PublicKey和PrivateKey了,那如何取到N、e、d這三個值呢。要取到這三個值,首先要將PublicKey和PrivateKey強(qiáng)制轉(zhuǎn)換成RSAPublicKey和RSAPrivateKey。共同的N值可以通過getModulus()獲取。執(zhí)行RSAPublicKey.getPublicExponent()可以獲取到公鑰中的e值,執(zhí)行RSAPrivateKey.getPrivateExponent()可以獲取私鑰中的d值。這三者返回類型都是BigInteger。代碼如下:

01// 打印公鑰信息
02public static void printPublicKeyInfo(PublicKey key){
03RSAPublicKey rsaPublicKey = (RSAPublicKey) publicKey;
04Log.d(MainActivity.TAG, 'RSAPublicKey:');
05Log.d(MainActivity.TAG, 'Modulus.length=' +
06rsaPublicKey.getModulus().bitLength());
07Log.d(MainActivity.TAG, 'Modulus=' +
08rsaPublicKey.getModulus().toString());
09Log.d(MainActivity.TAG, 'PublicExponent.length=' +
10rsaPublicKey.getPublicExponent().bitLength());
11Log.d(MainActivity.TAG, 'PublicExponent=' +
12rsaPublicKey.getPublicExponent().toString());
13}
14 
15// 打印私鑰信息
16public static void printPublicKeyInfo(PrivateKey key){
17RSAPrivateKey rsaPublicKey = (RSAPrivateKey) privateKey;
18Log.d(MainActivity.TAG, 'RSAPrivateKey:');
19Log.d(MainActivity.TAG, 'Modulus.length=' +
20rsaPrivateKey.getModulus().bitLength());
21Log.d(MainActivity.TAG, 'Modulus=' +
22rsaPrivateKey.getModulus().toString());
23Log.d(MainActivity.TAG, 'PublicExponent.length=' +
24rsaPrivateKey.getPrivateExponent().bitLength());
25Log.d(MainActivity.TAG, 'PublicExponent=' +
26rsaPrivateKey.getPrivateExponent().toString());
27}

        由于程序中動態(tài)生成KeyPair對明文加密后生成的密文是不可測的,所以在實際開發(fā)中通常在生成一個KeyPair后將公鑰和私鑰的N、e、d這三個特征值記錄下來,在真實的開發(fā)中使用這三個特征值再去將PublicKey和PrivateKey還原出來。還原方法如下:

01// 使用N、e值還原公鑰
02public static PublicKey getPublicKey(String modulus, String
03publicExponent)
04                throws NoSuchAlgorithmException, InvalidKeySpecException {
05        BigInteger bigIntModulus = new BigInteger(modulus);
06        BigInteger bigIntPrivateExponent = new BigInteger(publicExponent);
07        RSAPublicKeySpec keySpec = new RSAPublicKeySpec(bigIntModulus,
08bigIntPrivateExponent);
09        KeyFactory keyFactory = KeyFactory.getInstance('RSA');
10        PublicKey publicKey = keyFactory.generatePublic(keySpec);
11        return publicKey;
12}
13 
14// 使用N、d值還原公鑰
15public static PrivateKey getPrivateKey(String modulus, String
16privateExponent)
17                throws NoSuchAlgorithmException, InvalidKeySpecException {
18        BigInteger bigIntModulus = new BigInteger(modulus);
19        BigInteger bigIntPrivateExponent = new BigInteger(privateExponent);
20        RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(bigIntModulus,
21 bigIntPrivateExponent);
22        KeyFactory keyFactory = KeyFactory.getInstance('RSA');
23        PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
24        return privateKey;
25}

        公鑰和私鑰都具備后,就可以使用加解密的工具類javax.crypto.Cipher對明文和密文進(jìn)行處理了。與所有的引擎類一樣,可以通過調(diào)用Cipher類中的getInstance(String transformation)靜態(tài)工廠方法得到Cipher對象。該方法中的參數(shù)描述了由指定輸入產(chǎn)生輸出所進(jìn)行的操作或操作集合,可以是下列兩種形式之一:“algorithm/mode/padding”或“algorithm”。例如下面的例子就是有效的transformation形式:'DES/CBC/PKCS5Padding'或'DES'。如果沒有指定模式或填充方式,就使用特定提供者指定的默認(rèn)模式或默認(rèn)填充方式。

        Cipher的加密和解密方式所調(diào)用的方法和過程都一樣,只是傳參不同的區(qū)別。如下代碼:

1// 編碼前設(shè)定編碼方式及密鑰
2cipher.init(mode, key);
3// 傳入編碼數(shù)據(jù)并返回編碼結(jié)果
4byte[] dataResult = cipher.doFinal(input);

        Cipher.init(mode, key)方法中MODE指加密或解密模式,值為Cipher.ENCRYPT_MODE或Cipher.DECRYPT_MODE,參數(shù)key在加密時傳入PublicKey,在解密時以PrivateKey傳入。Cipher.doFinal(byte[] data)則是將待編碼數(shù)據(jù)傳入后并返回編碼結(jié)果。為了將編碼結(jié)果轉(zhuǎn)為可讀字符串,通常最后還使用BASE 64算法對最終的byte[]數(shù)據(jù)編碼后顯示給開發(fā)者。

        Demo運(yùn)行效果如下圖所示:

QQ截圖20120803161644.png

2012-8-3 17:06:52 上傳


圖17-4  使用動態(tài)生成的公鑰和私鑰進(jìn)行RSA加密


QQ截圖20120803161651.png

2012-8-3 17:06:58 上傳


圖17-5  使用預(yù)設(shè)的N、e、d值進(jìn)行RSA加密

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多