2011-05-25 43 views
1

我一直在努力閱讀一個公鑰文件,我希望獲取文件中的密鑰並使用它來加密另一個文件。我使用RSA PKCS1 v1.5加密並用SH1散列algorythim簽名文件,但那不是問題,問題是我已經提供了公鑰文件以便在加密時使用,而且我看起來似乎不能贏取閱讀該文件並生成一個publicKey對象。閱讀公鑰文件並使用密鑰加密另一個文件的問題

下面的代碼:

void setPublicKey(String file) 
{ 
    try 
    { 
     FileInputStream keyfis = new FileInputStream(file); 
     byte[] encKey = new byte[keyfis.available()]; keyfis.read(encKey); 
     keyfis.close(); 
     X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(encKey); 
     KeyFactory keyFactory = KeyFactory.getInstance("RSA"); 
// I get an exception on the below line 
     publicKey = keyFactory.generatePublic(pubKeySpec); 
    } catch (Exception e) 
     { 
     e.printStackTrace(); 
     } 
} 

可有人請幫助!

+0

你確信有沒有一個換行符在文件的結尾,對不對?由於您正在將整個文件讀入字節數組,因此您需要注意這一點。 – stevevls 2011-05-25 12:21:02

+0

如何檢查?順便說一句,我得到的異常是一個InvalidKeySpecException:InvalidKeyException:無效的密鑰格式。 – Yolo 2011-05-25 13:52:28

+0

不,沒有新的路線。 – Yolo 2011-05-25 13:56:54

回答

1

AFAIK X509編碼密鑰是使用ASN.1編碼的二進制文件。因此,最後關於新線的問題沒有任何意義。

如果你有一個文本文件,你有一個PEM編碼文件,我目前不知道你在這種情況下必須使用哪個KeySpec。

您可以將PEM編碼密鑰轉換爲DER編碼密鑰(例如使用OpenSSL),或者您可以使用BouncyCastle作爲加載PEM編碼密鑰的支持。

順便說一句:使用keyfis.read(encKey);是危險的,因爲read方法只讀取encKey字節,但不必。更好地從InputStream創建一個DataInputStream和使用的readFully(encKey):

new DataInputStream(keyfis).readFully(encKey); 
+0

另外,使用'available()'確定文件長度是* wrong *。使用['File.length()'](http://download.oracle.com/javase/6/docs/api/java/io/File.html#length())來確定文件長度。 – erickson 2011-05-25 15:42:42

+0

我仍然得到同樣的異常,但現在IOException異常:空,這裏是堆棧跟蹤:java.security.spec.InvalidKeySpecException:java.security.InvalidKeyException:我 OException:空 在sun.security.rsa.RSAKeyFactory.engineGeneratePublic (未知來源) 在java.security.KeyFactory.generatePublic(未知來源) 在Trunk.Main.setPublicKey(Main.java:425) 在Trunk.Main.Encryption(Main.java:282) 在Trunk.Main .main(Main.java:92) – Yolo 2011-05-26 08:10:10

+0

正如我寫的,它看起來像你有一個PEM編碼密鑰 - 並且你不能使用X509EncodedKeySpec加載一個PEM編碼密鑰 – Robert 2011-05-26 14:57:29

1

找到了解決辦法,但目前還不能確定,如果它的正確的解決方案怎麼我還是要拿到專用密鑰和解密的文件,但現在我是能夠使用提供的PublicKey作爲模數對其進行加密,但我沒有指數,我只是使用了一些常用數字「65537」作爲指數 我讀過它並不是加密的關鍵部分。

我不得不改變邏輯使用RSAPublicKeySpec(它使用BigInteger和Base64Decoder)而不是X509EncodedKeySpec來設置KeySpec 並繼續使用KeyFactory對象來生成公鑰。 現在這個邏輯需要模數和指數。

byte[] buffer = new byte[(int) new File(file).length()]; 
BufferedInputStream f = new BufferedInputStream(new FileInputStream(file)); 
f.read(buffer); 
String modulusBase64 = new String(buffer); 
BASE64Decoder b64dec = new BASE64Decoder(); 
String exponentBase64 = "65537"; 
RSAPublicKeySpec publicKeySpec = new RSAPublicKeySpec(new BigInteger (1,      b64dec.decodeBuffer(modulusBase64)), new BigInteger(1,  b64dec.decodeBuffer(exponentBase64))); 
KeyFactory publicKeyFactory = KeyFactory.getInstance("RSA"); 
publicKey = publicKeyFactory.generatePublic(publicKeySpec); 

//這是文件中的公鑰。 「J45t4SWGbFzeNuunHliNDZcLVeFU7lOpyNkX1xX + sVNaVJK8Cr0rSjUkDC8h9n + Zg7m0MVYk0byafPycmzWNDynpvj2go9mXwmUpmcQprX1vexxT5j1XmAaBZFYaJRcPWSVU92pdNh1Sd3USdFjgH0LQ5B3s8F95xdyc/5I5LDKhRobx6c1gUs/rnJfJjAgynrE4AsNsNem + STaZWjeb4J + f5Egy9xTSEl6UWxCClgCwhXopy10cBlH8CucpP0cyckOCIOloJ7mEMRCIpp6HPpYexVmXXSikTXh7aQ7tSlTMwUziIERc/zRpyj1Nk96Y7V8AorLFrn1R4Of66mpAdQ ==」