2009-11-02 108 views
7

我想在Java和PHP中實現RSA加密,但我似乎無法讓PHP識別我的Java公鑰/私鑰。下面是Java代碼編碼/解碼的公鑰和私鑰:RSA加密:Java到PHP

public static byte[] EncodePublicKey(PublicKey _publickey) throws Exception 
{ 
    return _publickey.getEncoded(); 
} 

public static PublicKey DecodePublicKey(byte[] _encodedkey) throws Exception 
{ 
    KeyFactory fac = KeyFactory.getInstance("RSA"); 
    X509EncodedKeySpec encodedKey = new X509EncodedKeySpec(_encodedkey); 
    return fac.generatePublic(encodedKey); 
} 

public static byte[] EncodePrivateKey(PrivateKey _privatekey) throws Exception 
{ 
    return _privatekey.getEncoded(); 
} 

public static PrivateKey DecodePrivateKey(byte[] _encodedkey) throws Exception 
{ 
    KeyFactory fac = KeyFactory.getInstance("RSA"); 
    PKCS8EncodedKeySpec encodedKey = new PKCS8EncodedKeySpec(_encodedkey); 
    return fac.generatePrivate(encodedKey); 
} 

我第一次使用PEAR Crypt_RSA功能試過,但它不支持X.509或PKCS8(它只是簡單的base64編碼的序列化模數,指數和鍵類型)。然後,我嘗試了OpenSSL「openssl_get_publickey」函數,但它似乎也沒有識別格式。

任何幫助,將不勝感激o.O

回答

10

你需要從Java二進制格式(DER)轉換爲PEM OpenSSL的(和PHP綁定)。您可以通過在命令行上指定-inform DER選項,使用OpenSSL命令行測試Java密鑰文件。

<? 
function pem2der($pem_data) { 
    $begin = "KEY-----"; 
    $end = "-----END"; 
    $pem_data = substr($pem_data, strpos($pem_data, $begin)+strlen($begin)); 
    $pem_data = substr($pem_data, 0, strpos($pem_data, $end)); 
    $der = base64_decode($pem_data); 
    return $der; 
} 

function der2pem($der_data) { 
    $pem = chunk_split(base64_encode($der_data), 64, "\n"); 
    $pem = "-----BEGIN PUBLIC KEY-----\n".$pem."-----END PUBLIC KEY-----\n"; 
    return $pem; 
} 

// load the public key from a DER-encoded file 
$pubkey = der2pem(file_get_contents("pubkey")); 
?> 

有關在Java中使用OpenSSL密鑰的更多信息,請參閱check out this link

+0

那麼我怎麼能在PHP中將ASN.1編碼轉換爲PEM格式呢? – user201117 2009-11-02 18:50:47

+0

找到上面的鏈接後更新了我的答案... – jheddings 2009-11-02 19:41:02

+0

這工作!謝謝=) – user201117 2009-11-02 20:53:16

5

PHP函數需要PEM編碼密鑰。把DER編碼的密鑰轉換成PEM是很簡單的。

這裏是我的代碼轉換PKCS#8的私鑰PEM,

function pkcs8_to_pem($der) { 

    static $BEGIN_MARKER = "-----BEGIN PRIVATE KEY-----"; 
    static $END_MARKER = "-----END PRIVATE KEY-----"; 

    $value = base64_encode($der); 

    $pem = $BEGIN_MARKER . "\n"; 
    $pem .= chunk_split($value, 64, "\n"); 
    $pem .= $END_MARKER . "\n"; 

    return $pem; 
} 

對於X509公鑰,在標記與公共取代私人。

+0

這和接受的答案是一樣的,但後來。 – user201117 2009-11-02 20:54:07

1

您也可以嘗試使用CastleCrypt,它允許一個易於使用的JAVA RSA加密和PHP:https://github.com/wessnerj/CastleCrypt

對於密鑰生成,你可能想使用OpenSSL來試試吧:

openssl genrsa -out privateKey.pem 2048 
openssl pkcs8 -topk8 -nocrypt -in privateKey.pem -outform der -out privateKey.der 
openssl rsa -in privateKey.pem -pubout -outform PEM -out publicKey.pem 
openssl rsa -in privateKey.pem -pubout -outform DER -out publicKey.der 

這個命令給你DER和PEM格式的私鑰和公鑰。對於JAVA,您必須使用.der鍵和PHP .pem鍵。