如何將SecretKeySpec
或SecretKey
的數據從Java
發送到PHP
?當我將它轉換爲String
(用RSA進行加密併發布到PHP)時,我會得到一些帶有問號的鑽石。如何將SecretKey從Java發送到PHP? (使用Android Studio&PhpStorm)
我試圖使用utf8_decode
但這個問題仍然存在。
編輯:
我產生RSA密鑰在PHP,並將其發送公鑰到Java。在Java中,我想生成AES_Key並使用AES加密明文,並將加密的明文和AES_Key(用RSA_Public_Key加密)從Java發送到PHP。 下面的代碼表示此項目的AES加密/解密步驟:
的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);
}
}
?>
生成祕密密鑰(如AES密鑰),明文加密(名稱),通過AES密鑰,加密AES密鑰,並準備發送到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代碼使用NameString的RSA私鑰解密的解密AES密鑰解密通過AES密鑰:
$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);
是這些類彼此匹配?
如何使用AES_Key(或Java中生成的SecretKey的副本)在Java中使用Java加密明文?
如何使用AES_key(由RSA私鑰解密)在PHP中解密純文本?
你的問題沒有代碼。你應該改變這一點。此外,您不會將數據從一個IDE發送到下一個。 IDE只是編寫代碼的工具。它不承載服務。最後,你有沒有聽說過Base64編碼? –
@ArtjomB。可能他試圖將相同的密鑰放到兩個平臺上進行調試。 –
你對「RSA加密」有什麼意義? –