Что такое PHP-эквивалент расшифровки Java RSA?
Здесь я пытаюсь внедрить Samsung Pay на PHP, но до сих пор мне не удалось правильно расшифровать процесс.
Ниже приведен пример кода Java, который я пытаюсь перенести на PHP:
import java.io.*;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import javax.crypto.*;
public static void main(String[] args) {
String encPayload = {{encryptedPayload}};
String privateKeyFilePath = "./rsapriv.pem";
getDecryptedData(encPayload, privateKeyFilePath);
}
public static String getDecryptedData(String encPayload, String privateKeyFilePath) {
String delims = "[.]";
String[] tokens = encPayload.split(delims);
Decoder urlDecoder = Base64.getUrlDecoder();
byte[] encKey = urlDecoder.decode(tokens[1]);
byte[] iv = urlDecoder.decode(tokens[2]);
byte[] cipherText = urlDecoder.decode(tokens[3]);
byte[] tag = urlDecoder.decode(tokens[4]);
byte[] plainText = new byte[cipherText.length];
try {
// Read private key file
File privateKeyFile = new File(privateKeyFilePath);
DataInputStream dis = new DataInputStream(new FileInputStream(privateKeyFile));
byte[] privKeyBytes = new byte[(int) privateKeyFile.length()];
dis.read(privKeyBytes);
dis.close();
// Set private key spec
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(privKeyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey privKey = keyFactory.generatePrivate(spec);
Cipher decryptCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
decryptCipher.init(Cipher.DECRYPT_MODE, privKey);
byte[] plainEncKey = decryptCipher.doFinal(encKey);
final Cipher aes128Cipher = Cipher.getInstance("AES/GCM/NoPadding");
final GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(16 * Byte.SIZE, iv);
final SecretKeySpec keySpec = new SecretKeySpec(plainEncKey, "AES");
aes128Cipher.init(Cipher.DECRYPT_MODE, keySpec, gcmParameterSpec);
int offset = aes128Cipher.update(cipherText, 0, cipherText.length, plainText, 0);
aes128Cipher.update(tag, 0, tag.length, plainText, offset);
aes128Cipher.doFinal(plainText, offset);
} catch (Exception e) {
}
return new String(plainText);
}
И вот что я пробовал до сих пор в PHP:
private function getDecryptedData($encPayload, $privateKeyFilePath) {
// Split the base64 encoded url
$tokens = explode('.', $encPayload);
// Convert to bytes
$header = base64_decode($tokens[0]);
$encKey = base64_decode($tokens[1]);
$iv = base64_decode($tokens[2]);
$cipherText = base64_decode($tokens[3]);
$tag = base64_decode($tokens[4]);
$plainText = "";
try {
$private = RSA::loadPrivateKeyFormat('PKCS8', $privateKeyFilePath)->withPadding(RSA::ENCRYPTION_PKCS1);
dd($private->decrypt($encKey));
// then some AES-128 GCM Stuff.
} catch (\Exception $ex) {
dd($ex->getMessage());
}
}
Я должен получить открытый текст, но вместо этого я получаю
Decryption error
сообщение, которое заставляет меня задуматься, правильно ли я это делаю или нет.
ОБНОВЛЕНИЕ: Раньше использовался синтаксис phpseclib v2.0, но теперь я изменил синтаксис на phpseclib v3.0.