1. 程式人生 > >Android公鑰私鑰及程式碼詳細解讀

Android公鑰私鑰及程式碼詳細解讀

一:關於公鑰加密和私鑰解密

(1)我有數字1和2,其中我喜歡2這個資料,就將2設定為我的私鑰,這樣私鑰就是我獨有的了,假設我有一個檔案,不想讓別人看到,就用公鑰1進行加密,這樣即使別人得到了這個檔案,也沒辦法解開,因為他只知道1是公鑰,只知道是1對檔案進行加密的,但是他不知道2是私鑰,2才是解密檔案的關鍵,而2又在我自己的手裡,所以除了我沒人能看到檔案具體的內容.
(2)常見的使用場景:
a:朋友間私密檔案的傳輸,朋友A用我提供的公鑰對傳輸的檔案進行加密,而我又將私鑰提供給A,那麼即使傳輸過程中檔案被竊取了,也沒辦法解開,因為私鑰只有我和A有,所以傳輸的檔案安全性非常高.
b.單向的檔案加密傳輸,路人A想要將非常重要的檔案傳給我,但是我很擔心傳輸的過程中檔案被竊取,所以我對A說不能用明文傳輸,就將公鑰給他,告訴他用公鑰對其加密後再傳給我,這樣加密後的檔案只能我自己看到,因為能解密的私鑰在自己手裡.
(3)注:因此加密的內容包含兩個部分,公開的金鑰即公鑰是人人都知道的,但是用公鑰加密的內容只有獨有的私鑰才能解開.
(4)作用:用於傳輸資料的加密.

二:關於私鑰簽名和公鑰驗籤.

(1)首先要明確一點:公鑰和私鑰都是可以對檔案進行加密的,並且可以雙向解密.
(2)那麼私鑰加密有什麼作用呢?
舉例:朋友A說有路人B冒充你在網上釋出訊息,那麼我就用私鑰加密了自己釋出到網上的明文,所有人都知道公鑰,所以都可以用公鑰解密檔案,那麼能用我公開的公鑰解密出來檔案必然是我用私鑰加密的,這樣就證明發布的內容確定是我寫的了.
(3)這種私鑰加密的做法叫做數字簽名,保證釋出內容方的真實性.

三:CMD實際操作:

(1)在CMD中輸入keytool -genkey

keystore金鑰庫口令為123456
金鑰口令為 abcdefg
這裡寫圖片描述

(2)關於”.keystore”

以上的操作將會生成一個公鑰和私鑰,預設使用的是非對稱加密的DSA演算法,同時上述操作還會建立一個數字證書,證書中包含的不僅僅是新生成的公鑰,還包含了該公鑰對應的上述填寫的資訊的對應關係,上述資訊構建了X.500格式的全名,包含了主體的國家、州、城市、機構、單位和名字。這樣,這個證書將證明相應的公鑰是這個人或機構所擁有的.以上生成的公鑰,私鑰和證書都儲存在”.keystore”中.
這裡寫圖片描述

(3)對於2個密碼的區分

上面的keystore密碼:123456,是金鑰庫的密碼,也就是說每次進入金鑰庫都必須輸入該密碼
上面的mykey密碼:adcdefg,是隻對應別名”mykey”的密碼,使用該別名就可以在keystore中找到對應的公鑰,私鑰和證書,此處對應的密碼是對於該別名私鑰的密碼,keystore中每個別名都可以用不同的密碼加以保護.

(4)在本地已經存在”.keystore”的情況下,如果在輸入”keytool -genkey”就會報錯,因為它會在”.keystore”中建立預設別名為”mykey”的證書,但是金鑰庫中的別名為”mykey”已經存在了,就會報錯.
這裡寫圖片描述

(5)在金鑰庫中利用別名增加多個證書.

在使用”keytool -genkey -alias aqiu”建立別名”aqiu”時,我輸入的”.keystore”密碼出錯的顯示.
這裡寫圖片描述
在輸入之前設定的密碼”123456”後,這樣就在keystore中建立了別名為”aqiu”的公鑰私鑰和證書了,
這裡寫圖片描述

(6)使用指定的演算法和金鑰庫設定有效期

之前我們都是使用的是預設的DSA演算法,並且都是儲存在”.keystore”金鑰庫中,而且還沒設定有效期.
keytool -genkey -alias aqiutest -keyalg RSA -keysize 1024 -keystore aqukeystore -validity 4000
這裡寫圖片描述
使用RSA演算法生成1024位別名為”aqiutest”的公鑰/私鑰對和證書,金鑰長度為1024位,該別名證書的有效期是4000天,使用的金鑰庫為”aqukeystore”檔案.
這裡寫圖片描述
其中金鑰庫的口令需要重新輸入不必和之前的keystore相同,可以設定為”654321”,別名”aqiutest”的密碼任意設定即可,這裡設定為”654321”,直接enter即可.

(7)將數字證書匯入到檔案

選擇”aqukeystore”金鑰庫,輸入金鑰庫密碼”654321”,在金鑰庫中選擇別名為”aqiutest”的公鑰和證書(注意:這裡只生成公鑰和證書,不需要私鑰所以不需要私鑰密碼,因此內容也是可以公開的),
keytool -export -alias aqiutest -file aqiutest.cer -keystore aqukeystore -storepass 654321 -rfc
這裡寫圖片描述
這樣在本地目錄下就生成了相關的證書
這裡寫圖片描述

由於該證書是用自己的私鑰對該證書進行數字簽名的,即自己給自己簽發的證書,因此視窗中顯示警告資訊:“該證書發行機構根證書沒受信任”。但其實並沒有什麼大礙,因為證書由我們釋出只需要在公司內部使用即可.
這裡寫圖片描述

(8)想得到證書更詳細的內容的指令

C:\Users\46210>keytool -printcert -file aqiutest.cer
所有者: CN=aqiu, OU=aqiu, O=aqiu, L=aqiu, ST=aqiu, C=aqiu
釋出者: CN=aqiu, OU=aqiu, O=aqiu, L=aqiu, ST=aqiu, C=aqiu
序列號: 1b397b28
有效期開始日期: Tue May 03 10:49:00 CST 2016, 截止日期: Fri Apr 16 10:49:00 CST 2027
證書指紋:
MD5: 22:F6:53:B0:5E:7A:CA:EE:4E:02:20:B3:79:B9:A9:5C
SHA1: 80:62:91:82:D5:A4:C3:82:70:BD:C4:12:75:FA:1B:C0:9C:30:EA:94
SHA256: E8:57:B9:BC:40:82:AC:68:37:CC:26:FE:FC:29:25:B4:FE:60:A0:8A:84:72:2B:B8:57:61:2C:92:3C:14:47:E8
簽名演算法名稱: SHA256withRSA
版本: 3

擴充套件:

1: ObjectId: 2.5.29.14 Criticality=false

SubjectKeyIdentifier [
KeyIdentifier [
0000: 8C B6 2C 06 46 90 20 11 19 D1 88 97 E0 53 DA F1 ..,.F. ……S..
0010: DE 28 72 C2 .(r.
]
]
這裡寫圖片描述

四:使用MyEclipse JAVA :安全證書-公鑰加密,私鑰解密示例程式

package com.aqiu.exchange;

import java.io.FileInputStream;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;

import javax.crypto.Cipher;

public class CodeUtils {

/**
* @param args
*/
public static void main(String[] args) throws Exception {
byte[] msg = “阿秋麼麼噠”.getBytes(“UTF8”); // 待加解密的訊息
// 用證書的公鑰加密
CertificateFactory cff = CertificateFactory.getInstance(“X.509”);
FileInputStream fis1 = new FileInputStream(
“C://Users//46210//aqiutest.cer”); // 證書檔案
Certificate cf = cff.generateCertificate(fis1);
PublicKey pk1 = cf.getPublicKey(); // 得到證書檔案攜帶的公鑰
Cipher c1 = Cipher.getInstance(“RSA/ECB/PKCS1Padding”); // 定義演算法:RSA
c1.init(Cipher.ENCRYPT_MODE, pk1);
byte[] msg1 = c1.doFinal(msg); // 加密後的資料
System.out.println(“加密之後的資料:”+msg1);
// 用證書的私鑰解密 - 該私鑰存在生成該證書的金鑰庫中
FileInputStream fis2 = new FileInputStream(“C://Users//46210//aqukeystore”);
KeyStore ks = KeyStore.getInstance(“JKS”); // 載入證書庫
char[] kspwd = “654321”.toCharArray(); // 證書庫密碼
char[] keypwd = “654321”.toCharArray(); // 證書密碼
ks.load(fis2, kspwd); // 載入證書
PrivateKey pk2 = (PrivateKey) ks.getKey(“aqiutest”, keypwd); // 獲取證書私鑰
fis2.close();
Cipher c2 = Cipher.getInstance(“RSA/ECB/PKCS1Padding”);
c2.init(Cipher.DECRYPT_MODE, pk2);
byte[] msg2 = c2.doFinal(msg1); // 解密後的資料
System.out.println(“解密之後的資料:”+new String(msg2, “UTF8”)); // 將解密資料轉為字串
}
}
這裡寫圖片描述
用公鑰加密之後,只有自己的私鑰才能解密.