2015-03-02 31 views
0

我在嘗試將Java生成的RSA公鑰轉換爲字符串格式時遇到問題,因此我可以在PHP端使用它。我試圖將其轉換爲字符串,但PHP側的加密失敗。我生成Java這樣的公共密鑰:將Java中的RSA公鑰發送到PHP服務器

KeyPairGenerator k = KeyPairGenerator.getInstance("RSA"); 
k.initialize(1024); 
KeyPair kp = k.genKeyPair(); 
PublicKey publicKey = kp.getPublic(); 
PrivateKey privateKey = kp.getPrivate(); 

和公鑰時輸出到字符串看起來是這樣的:

RSA Public Key 
    modulus: eded852d98899fd083b6b989cbdbb41c0cf604ccdc3c4b46a6e3bdf92be898db1c53133dba4fcbc3bd7e8934b7b212856146169858ef2177e9c04c995d4fb61f9957eb6ff61a1183de03e5459ecbae7d1196778be844127fd7e80668b57037cab7a3e56c02cb881c3fb2aaddd47e5cae49c14582be01722cfa5352d9bdc97a37 
    public exponent: 10001 

我再編碼這個公鑰是這樣的:

byte[] pKbytes = Base64.encode(publicKey.getEncoded(), 0); 
     String pK = new String(pKbytes); 
     String pubKey = "-----BEGIN PUBLIC KEY-----\n" + pK + "-----END PUBLIC KEY-----\n"; 

並且輸出看起來像這樣:

-----BEGIN PUBLIC KEY----- 
    MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDt7YUtmImf0 
    IO2uYnL27QcDPYEzNw8S0am4735 
    K+iY2xxTEz26T8vDvX6JNLeyEoVhRhaYWO8hd+nATJldT7Yf 
    mVfrb/YaEYPeA+VFnsuufRGWd4vo 
    RBJ/1+gGaLVwN8q3o+VsAsuIHD+yqt3UflyuScFFgr4Bciz 
    6U1LZvcl6NwIDAQAB 
    -----END PUBLIC KEY----- 

它看起來與我在PHP端的格式相似。使用Base64對其進行編碼,爲我提供了關鍵字String的最終格式。

LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS1NSUdmTUEwR0NTcUdTSWIzRFFFQkFRVUFBNEdOQURD 
QmlRS0JnUUR0N1lVdG1JbWYwSU8ydVluTDI3UWNEUFlFek53OFMwYW00NzM1SytpWTJ4eFRFejI2 
    VDh2RHZYNkpOTGV5RW9WaFJoYVlXTzhoZCtuQVRKbGRUN1lmbVZmcmIvWWFFWVBlQStWRm5zdXVm 
    UkdXZDR2b1JCSi8xK2dHYUxWd044cTNvK1ZzQXN1SUhEK3lxdDNVZmx5dVNjRkZncjRCY2l6NlUx 
    TFp2Y2w2TndJREFRQUItLS0tLUVORCBQVUJMSUMgS0VZLS0tLS0= 

畢竟這個關鍵似乎並不奏效。它使用我發送的密鑰加密消息,但是當我將它發送回Java/Android應用程序(其中包含私鑰)時,它無法解密它。反之亦然(即從PHP獲取編碼密鑰字符串並將其轉換爲公鑰以供Java/Android應用程序使用)我在這裏做的任何錯誤?我的直覺告訴我,我發送了錯誤的字符串到PHP服務器

下面是用Java堆棧跟蹤的樣子:

03-02 12:02:26.170 W/System.err﹕ java.lang.ArrayIndexOutOfBoundsException: too much data for RSA block 
03-02 12:02:26.182 W/System.err﹕ at com.android.org.bouncycastle.jcajce.provider.asymmetric.rsa.CipherSpi.engineDoFinal(CipherSpi.java:464) 
03-02 12:02:26.186 W/System.err﹕ at javax.crypto.Cipher.doFinal(Cipher.java:1204) 
03-02 12:02:26.186 W/System.err﹕ at com.app.test.NQ.NQCrypto.decrypt(NQCrypto.java:116) 

這裏是我試圖解密Java中的數據:

public static String decrypt(String data) throws Exception { 

     Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-1AndMGF1Padding", "BC"); 

     cipher.init(Cipher.DECRYPT_MODE, privateKey); 

     // Base 64 encode the encrypted data 
     byte[] encryptedBytes = Base64.encode(cipher.doFinal(data.getBytes()), 0); 

     return new String(encryptedBytes); 

    } 
+1

@ArtjomB。 phpseclib – Daniel 2015-03-02 12:02:40

+0

相關:http://stackoverflow.com/questions/22861824/key-format-need-to-use-in-crypt-rsa – 2015-03-02 12:07:27

+0

@Duncan它使用我發送的密鑰加密消息,但是當我發回它時到Java/Android應用程序(包含私鑰),它無法解密它 – Daniel 2015-03-02 12:07:31

回答

2

你解密代碼如下錯誤:

cipher.doFinal(data.getBytes()) 

data變量是一個字符串,但字符串不能保存原始加密數據而不會破壞它。除非你的密文實際上是十六進制編碼或base64編碼等。在這種情況下,getBytes()不是解碼成字節數組的正確方法。

因此,要麼修復您發送密文的方式,要麼更正將密文解碼爲字節數組的方式。

+0

你是一個拯救生命的人!並非完全正確的答案,但問題在於此。我不得不base64_decode字符串變量數據。 – Daniel 2015-03-02 12:59:02

+0

@Daniel那麼,*是*我在我的答案中建議的內容......「*或更正了將密文解碼爲字節數組的方式*」:-) – 2015-03-02 13:08:09