2014-05-06 182 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的回答!你还不能投票(没有足够的代表),但一旦你可以,你也可以投票答案。 –