How can I send the data of a SecretKeySpec
or SecretKey
from Java
to PHP
? When I convert it to String
(to encrypt with RSA and post to PHP), I get some diamond with a question mark in it.
I tried to use utf8_decode
but this problem is still remains.
EDIT:
I generated RSA Keypair in PHP, and sent the Public Key to Java. In Java I want to generate an AES_Key and encrypt a plaintext using AES, and send an encrypted plaintext and AES_Key (that is encrypted with RSA_Public_Key) from Java to PHP. The following codes represent the AES Encryption/Decryption steps of this project:
Java:
public static class ApiCrypter {
private String iv = "0000000000000000";
private byte[] secretkey; //="mysecretkeyyyyyy";
private IvParameterSpec ivspec;
private SecretKeySpec keyspec;
private Cipher cipher;
public ApiCrypter(byte[] key)
{
secretkey=key;
ivspec = new IvParameterSpec(iv.getBytes());
keyspec = new SecretKeySpec(secretkey, "AES");
try {
cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
}
}
public byte[] encrypt(String text) throws Exception
{
if(text == null || text.length() == 0) {
throw new Exception("Empty string");
}
byte[] encrypted = null;
try {
cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);
encrypted = cipher.doFinal(text.getBytes("UTF-8"));
}
catch (Exception e) {
throw new Exception("[encrypt] " + e.getMessage());
}
return encrypted;
}
public byte[] decrypt(String code) throws Exception
{
if(code == null || code.length() == 0) {
throw new Exception("Empty string");
}
byte[] decrypted = null;
try {
cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec);
decrypted = cipher.doFinal(hexToBytes(code));
}
catch (Exception e) {
throw new Exception("[decrypt] " + e.getMessage());
}
return decrypted;
}
public static String bytesToHex(byte[] data)
{
if (data==null) {
return null;
}
int len = data.length;
String str = "";
for (int i=0; i<len; i++) {
if ((data[i]&0xFF)<16) {
str = str + "0" + java.lang.Integer.toHexString(data[i]&0xFF);
}
else {
str = str + java.lang.Integer.toHexString(data[i]&0xFF);
}
}
return str;
}
public static byte[] hexToBytes(String str) {
if (str==null) {
return null;
}
else if (str.length() < 2) {
return null;
}
else {
int len = str.length() / 2;
byte[] buffer = new byte[len];
for (int i=0; i<len; i++) {
buffer[i] = (byte) Integer.parseInt(str.substring(i*2,i*2+2),16);
}
return buffer;
}
}
}
PHP:
<?php
class ApiCrypter
{
private $iv = '0000000000000000';
private $key;// = '89432hjfsd891787';
public function __construct($keyy)
{
$this->key = $keyy;
}
public function encrypt($str)
{
$encrypted = openssl_encrypt($str, 'AES-128-CBC', $this->key, 0, $this->iv);//
return bin2hex($encrypted);
}
public function decrypt($code)
{
$code = $this->hex2bin($code);
$decrypted = openssl_decrypt($code, 'AES-128-CBC', $this->key, 0, $this->iv);
$ut = utf8_encode(trim($decrypted));
// return $this->pkcs5_unpad($ut);
return $ut;
}
protected function hex2bin($hexdata)
{
$bindata = '';
for ($i = 0; $i < strlen($hexdata); $i += 2) {
$bindata .= chr(hexdec(substr($hexdata, $i, 2)));
}
return $bindata;
}
protected function pkcs5_pad($text)
{
$blocksize = 16;
$pad = $blocksize - (strlen($text) % $blocksize);
return $text . str_repeat(chr($pad), $pad);
}
protected function pkcs5_unpad($text)
{
$pad = ord($text{strlen($text) - 1});
if ($pad > strlen($text)) {
return false;
}
if (strspn($text, chr($pad), strlen($text) - $pad) != $pad) {
return false;
}
return substr($text, 0, -1 * $pad);
}
}
?>
Generating a secretKey (as AES key), encryption of the plaintext(name) by AES key, Encrypt AES key, and preparing them for sending to PHP:
SecureRandom secureRandom = new SecureRandom();
KeyGenerator keyGenerator;
keyGenerator = KeyGenerator.getInstance("AES");
keyGenerator.init(256, secureRandom);
SecretKey key = keyGenerator.generateKey();
secret_key = key.getEncoded();
Byte[] encodedSessionKey = RSA.encryptByPublicKey(secret_key, public_key);
ApiCrypter apiCrypter=new ApiCrypter(encodedSessionKey);
String encryptedName = ApiCrypter.bytesToHex(apiCrypter.encrypt(nameStr));
String encodedStr = Base64.encodeToString(encodedSessionKey, Base64.DEFAULT);
AsyncDataClass asyncRequestObject = new AsyncDataClass();
asyncRequestObject.execute(serverUrl,encodedStr,encryptedName);
PHP code to decrypt AES key using of the RSA private key and decryption of the NameString by decrypted AES key:
$encodedStr = "";
$encryptedName = "";
if(isset($_POST['encodedStr'])){
$encodedSecretKey = $_POST['encodedStr'];
}
if(isset($_POST['encryptedName'])){
$encryptedName = $_POST['encryptedName'];
}
$rsa = new \phpseclib\Crypt\RSA();
$rsa->setHash('sha1');
$rsa->setMGFHash('sha1');
$rsa->setEncryptionMode(1);
$rsa->loadKey(file_get_contents('private.key')); // RSA Private key
$AES_session_key = $rsa->decrypt(base64_decode($encodedSecretKey));
$ApiCrypter= new ApiCrypter($AES_session_key);
$decryptedName = $ApiCrypter->decrypt($encryptedName);
Are these classes match to each other?
How to encrypt a plaintext in Java using of the AES_Key (or a copy of a SecretKey that is generated in Java)?
How to decrypt a plaintext in PHP, using the AES_key(that is decrypted by RSA Private Key) ?