1. 程式人生 > >Java/PHP/C ... 幾種語言 RSA 的互操作

Java/PHP/C ... 幾種語言 RSA 的互操作

最近有一個專案,涉及到和別的網站合作,雙方通訊的鑑權計劃是通過 RSA 來做。由於可能涉及到不同的開發環境,於是要研究一下各個語言對 RSA 的支援

openssl 預設創建出來的公金鑰檔案是 PEM 格式的,但 Java API 匯入密碼只能是 DER 格式,特別是金鑰必須用 PKCS#8 編碼。這就需要對 openssl 產生出來的檔案做一下轉換

    • openssl rsa -inform PEM -in rsapriv.pem -outform DER -pubout -out rsapub.der
    • openssl pkcs8 -topk8 -inform PEM -in rsapriv.pem -outform DER -nocrypt -out rsapriv.der
  1. 基礎演算法的標準是 openssl 的:RSA_private_encrypt/RSA_public_decrypt、RSA_public_encrypt/RSA_private_decrypt 這4個函式,因為 PHP 的 openssl 模組也只提供了這 4 個基礎函式(不要幻想用非 openssl 模組之外的東西來做 RSA 運算,比如 PEAR 的 Crypt_RSA,速度慢到令人髮指)
  2. 要注意上述 4 個函式裡,可使用的 padding 引數只有那麼有限的幾種。對應 Java 裡面 Cipher.getInstance() 的引數,只能用 "RSA/NONE/PKCS1Padding" 或 "RSA/NONE/NoPadding"(或許 "RSA/None/OAEPPadding" 是對應RSA_PKCS1_OAEP_PADDING,但我沒有深究了)。預設 PHP 裡的 padding 是 RSA_PKCS1_PADDING
  3. 關於 python... 嗯,直接用 ctypes 就好啦
  4. 用 RSA 簽名都是首先將文字做一個單向 hash,然後用私鑰將簽名加密;校驗端拿到簽名和文字,用公鑰將簽名解密,對比是否是文字的 hash。openssl 因此封裝了 RSA_sign/RSA_verify 來做這個事情。

    總之為了更多語言的互操作能力,我們現在沒有用 RSA_sign/RSA_verify 這兩個封裝好的函式。