2014-05-06 293 views
1

我有嚴重的問題,我希望會是一個簡單的調用PHP的 openssl_public_encrypt();加密密碼(RSA)與公鑰

可悲的是,我得到一個無效的公鑰警告。

我的目標是簡單的RSA加密使用他們的API提供公鑰目前看起來是這樣的一個用戶密碼:

+ Tir6 + unMOaQ5tHqjjjwnlAMhccnCSMFEi3a0mhIxbW + O/GukjomGyzckQT2h0Ys70JezHbNq5YS3sYkNF29kCkz4HuNfy9eEjE/clA9/zyfT8ZcbnusLcLz2xNgbTp62fQdzBnReI5 +民主黨/ N24krYvHaYIr8ACxDqBv2TR3E9M = AQAB

顯然使用我想相同的服務工作,以實現使用中發現這些步驟的解決方案:

  1. 從中提取係數和指數公鑰
  2. 重新構建在MS PUBLICKEYBLOB格式的關鍵
  3. 呼叫的OpenSSL轉換的關鍵PEM格式
  4. 負載從轉換後的文件
  5. 的PEM公共密鑰
  6. 對密碼進行加密

但是(轉換爲UTF-16LE後),不僅我不知道它有可能在PHP做的,我覺得必須有一個更簡單的方法!

我看到的一篇文章暗示說指數可能會出現在最後一個符號(如此AQAB)之後,但我不知道這是否可靠。

+0

爲什麼你想要加密密碼而不是散列呢? – kero

+1

我真的不明白他們爲什麼不接受哈希,甚至不使用HTTPS作爲SOAP服務。這很可笑。即使他們堅持這樣的RSA加密,當然也沒有必要在運行中創建證書。可悲的是,這不是我的API來編輯。 –

+0

不,你不能使用最後一個=符號來拆分,只是刪除AQAB可能會工作。如果密鑰是3個字節的倍數(例如3072位),那麼將不存在=符號。 –

回答

1

像這樣的東西你想要做什麼?:

<?php 
$key = '+Tir6+unMOaQ5tHqjjjwnlAMhccnCSMFEi3a0mhIxbW+O/GukjomGyzckQT2h0Ys70JezHbNq5YS3sYkNF29kCkz4HuNfy9eEjE/clA9/zyfT8ZcbnusLcLz2xNgbTp62fQdzBnReI5+dpj/N24krYvHaYIr8ACxDqBv2TR3E9M=AQAB'; 

include('Crypt/RSA.php'); 

$rsa = new Crypt_RSA(); 
$rsa->loadKey(array(
    'e' => new Math_BigInteger(65537), 
    'n' => new Math_BigInteger(substr($key, 0, -4), -256) 
)); 
$ciphertext = $rsa->encrypt('password'); 

echo bin2hex($ciphertext); 
?> 

本例使用phpseclib, a pure PHP RSA implementation。儘管phpseclib不支持您發佈的密鑰的格式,但它支持原始公鑰,因此轉換爲PKCS1樣式的密鑰是不必要的。而phpseclib生成的密文完全是interoperable with OpenSSL

+0

這基本上是我最終做的。非常感謝! –

0

OK,所以你需要做什麼:

  1. 刪除AQAB部分,並使用值65537爲公用指數
  2. 基地64解碼模
  3. 創建公衆的DER編碼鍵入PKCS#1格式(見下文)
  4. base64使用64字符行長度和DOS行結尾編碼DER編碼
  5. 添加PEM標頭&頁腳
  6. 使用PEM編碼字符串創建一個公共密鑰和最後
  7. 加密

以下ASN.1規範定義在PKCS#公鑰密碼1格式:

RSAPublicKey ::= SEQUENCE { 
     modulus   INTEGER, -- n 
     publicExponent INTEGER -- e 
} 

現在SEQUENCE的標識符八位字節或標籤是十六進制的30,INTEGER是02,長度應指定爲like this。所以,你喜歡的東西:以十六進制

30818902818100F938ABEBEBA730E690E6D1EA8E38F09E500C85C727092305122DDAD26848C5B5BE3BF1AE923A261B2CDC9104F687462CEF425ECC76CDAB9612DEC624345DBD902933E07B8D7F2F5E12313F72503DFF3C9F4FC65C6E7BAC2DC2F3DB13606D3A7AD9F41DCC19D1788E7E7698FF376E24AD8BC769822BF000B10EA06FD9347713D30203010001 

。經過這麼基地64編碼,並添加頁眉和頁腳行,你應該得到:

-----BEGIN RSA PUBLIC KEY----- 
MIIBCgKCAQH5OKvr66cw5pDm0eqOOPCeUAyFxycJIwUSLdrSaEjFtb478a6SOiYbLNyRBPaHRizvQl7Mds2rlhLexiQ0Xb2QKTPge41/L14SMT9yUD3/PJ9Pxlxue6wt 
wvPbE2BtOnrZ9B3MGdF4jn52mP83biSti8dpgivwALEOoG/ZNHcT0wIDAQAB 
-----END RSA PUBLIC KEY----- 

編碼愉快。

+0

這是一篇有用的文章,但最終使用pspseclib中的Crypt_RSA更簡單(如neubert的回覆中所述)。非常感謝 –

+0

@TomBrown沒問題,別忘了接受neuberts的回答!你還不能投票(沒有足夠的代表),但一旦你可以,你也可以投票答案。 –