Ale*_*tes 9 php rsa bouncycastle public-key-encryption phpseclib
我在php中有一个web服务,它生成一个用于加密消息的密钥对,以及一个用于检索私钥并解密消息的java应用程序.
对于php我正在使用http://phpseclib.sourceforge.net/并拥有这两个文件:
keypair.php
<?php
set_time_limit(0);
if( file_exists('private.key') )
{
echo file_get_contents('private.key');
}
else
{
include('Crypt/RSA.php');
$rsa = new Crypt_RSA();
$rsa->createKey();
$res = $rsa->createKey();
$privateKey = $res['privatekey'];
$publicKey = $res['publickey'];
file_put_contents('public.key', $publicKey);
file_put_contents('private.key', $privateKey);
}
?>
Run Code Online (Sandbox Code Playgroud)
encrypt.php
<?php
include('Crypt/RSA.php');
//header("Content-type: text/plain");
set_time_limit(0);
$rsa = new Crypt_RSA();
$rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_OAEP);
$rsa->loadKey(file_get_contents('public.key')); // public key
$plaintext = 'Hello World!';
$ciphertext = $rsa->encrypt($plaintext);
echo base64_encode($ciphertext);
?>
Run Code Online (Sandbox Code Playgroud)
在java中我有这个代码:
package com.example.app;
import java.io.DataInputStream;
import java.net.URL;
import java.security.Security;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import sun.misc.BASE64Decoder;
public class MainClass {
/**
* @param args
*/
public static void main(String[] args)
{
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
try {
BASE64Decoder decoder = new BASE64Decoder();
String b64PrivateKey = getContents("http://localhost/api/keypair.php").trim();
String b64EncryptedStr = getContents("http://localhost/api/encrypt.php").trim();
System.out.println("PrivateKey (b64): " + b64PrivateKey);
System.out.println(" Encrypted (b64): " + b64EncryptedStr);
SecretKeySpec privateKey = new SecretKeySpec( decoder.decodeBuffer(b64PrivateKey) , "AES");
Cipher cipher = Cipher.getInstance("RSA/None/OAEPWithSHA1AndMGF1Padding", "BC");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] plainText = decoder.decodeBuffer(b64EncryptedStr);
System.out.println(" Message: " + plainText);
}
catch( Exception e )
{
System.out.println(" Error: " + e.getMessage());
}
}
public static String getContents(String url)
{
try {
String result = "";
String line;
URL u = new URL(url);
DataInputStream theHTML = new DataInputStream(u.openStream());
while ((line = theHTML.readLine()) != null)
result = result + "\n" + line;
return result;
}
catch(Exception e){}
return "";
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题是:
在上述答案的帮助下,我发现 SecretKeySpec 使用错误,并且我发现来自 OpenSSL 的 PEM 文件不是“标准格式”,因此我需要使用 PEMReader 将其转换为 PrivateKey 类。
这是我的工人阶级:
package com.example.app;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.StringReader;
import java.net.URL;
import java.security.KeyPair;
import java.security.PrivateKey;
import java.security.Security;
import javax.crypto.Cipher;
import org.bouncycastle.openssl.PEMReader;
import sun.misc.BASE64Decoder;
public class MainClass {
/**
* @param args
*/
public static void main(String[] args)
{
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
try {
BASE64Decoder decoder = new BASE64Decoder();
String b64PrivateKey = getContents("http://localhost/api/keypair.php").trim();
String b64EncryptedStr = getContents("http://localhost/api/encrypt.php").trim();
System.out.println("PrivateKey (b64): " + b64PrivateKey);
System.out.println(" Encrypted (b64): " + b64EncryptedStr);
byte[] decodedKey = decoder.decodeBuffer(b64PrivateKey);
byte[] decodedStr = decoder.decodeBuffer(b64EncryptedStr);
PrivateKey privateKey = strToPrivateKey(new String(decodedKey));
Cipher cipher = Cipher.getInstance("RSA/None/OAEPWithSHA1AndMGF1Padding", "BC");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] plainText = cipher.doFinal(decodedStr);
System.out.println(" Message: " + new String(plainText));
}
catch( Exception e )
{
System.out.println(" Error: " + e.getMessage());
}
}
public static String getContents(String url)
{
try {
String result = "";
String line;
URL u = new URL(url);
DataInputStream theHTML = new DataInputStream(u.openStream());
while ((line = theHTML.readLine()) != null)
result = result + "\n" + line;
return result;
}
catch(Exception e){}
return "";
}
public static PrivateKey strToPrivateKey(String s)
{
try {
BufferedReader br = new BufferedReader( new StringReader(s) );
PEMReader pr = new PEMReader(br);
KeyPair kp = (KeyPair)pr.readObject();
pr.close();
return kp.getPrivate();
}
catch( Exception e )
{
}
return null;
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的 keypair.php
<?php
set_time_limit(0);
if( file_exists('private.key') )
{
echo base64_encode(file_get_contents('private.key'));
}
else
{
include('Crypt/RSA.php');
$rsa = new Crypt_RSA();
$rsa->setHash('sha1');
$rsa->setMGFHash('sha1');
$rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_OAEP);
$rsa->setPrivateKeyFormat(CRYPT_RSA_PRIVATE_FORMAT_PKCS1);
$rsa->setPublicKeyFormat(CRYPT_RSA_PUBLIC_FORMAT_PKCS1);
$res = $rsa->createKey(1024);
$privateKey = $res['privatekey'];
$publicKey = $res['publickey'];
file_put_contents('public.key', $publicKey);
file_put_contents('private.key', $privateKey);
echo base64_encode($privateKey);
}
?>
Run Code Online (Sandbox Code Playgroud)
和我的 encrypt.php
<?php
include('Crypt/RSA.php');
set_time_limit(0);
$rsa = new Crypt_RSA();
$rsa->setHash('sha1');
$rsa->setMGFHash('sha1');
$rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_OAEP);
$rsa->loadKey(file_get_contents('public.key')); // public key
$plaintext = 'Hello World!';
$ciphertext = $rsa->encrypt($plaintext);
$md5 = md5($ciphertext);
file_put_contents('md5.txt', $md5);
file_put_contents('encrypted.txt', base64_encode($ciphertext));
echo base64_encode($ciphertext);
?>
Run Code Online (Sandbox Code Playgroud)
我希望它对任何人都有帮助,谢谢。