Mam usługę internetową w php, która generuje parę kluczy do zaszyfrowania wiadomości, oraz jedną aplikację w języku Java, która odbiera privatekey i odszyfrowuje wiadomość.Szyfrowanie PHP, deszyfrowanie Java
dla PHP używam http://phpseclib.sourceforge.net/ i mieć to dwa pliki:
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);
}
?>
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);
?>
w java Mam ten kod:
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 "";
}
}
Moje pytania są następujące:
- Dlaczego mam wyjątek mówiąc "nie klucz RSA!"?
- Jak mogę poprawić ten kod? Użyłem base64, aby uniknąć błędów kodowania i komunikacji między Javą i PHP.
- Ta koncepcja jest poprawna? Mam na myśli, używam go poprawnie?
Czy dane pre-base64 pasują do odkodowanych danych base64? –
Tak, testowałem to teraz, a suma kontrolna md5 napisu PHP i Java po dekodowaniu z base64 jest taka sama. –
Może moje SecretKeySpec są błędne? Próbowałem zmienić wartość algorytmu, bez powodzenia. –