Impossible d'échanger des données cryptées avec AES-256 entre Java et PHP
Mon problème est le suivant: ce que j'ai chiffrer en Java je peux déchiffrer parfaitement en Java, mais PHP mcrypt
ne peut pas déchiffrer. Ce que j'ai chiffrer avec mcrypt
je peux déchiffrer avec mcrypt
mais ne peut pas en Java.
Je veux envoyer et de recevoir des données chiffrées à partir d'une application Java pour une page PHP, j'ai donc besoin d'elle pour être compatible.
Voici ce que j'ai...
JAVA...
public static String crypt(String input, String key){
byte[] crypted = null;
try{
SecretKeySpec skey = new SecretKeySpec(Base64.decodeBase64(key), "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, skey);
crypted = cipher.doFinal(input.getBytes());
}catch(Exception e){
}
return Base64.encodeBase64String(crypted);
}
public static String decrypt(String input, String key){
byte[] output = null;
try{
SecretKeySpec skey = new SecretKeySpec(Base64.decodeBase64(key), "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, skey);
output = cipher.doFinal(Base64.decodeBase64(input));
}catch(Exception e){
}
return new String(output);
}
En cours d'exécution:
public static void main(String[] args) {
String key = "Zvzpv8/PXbezPCZpxzQKzL/FeoPw68jIb+NONX/LIi8=";
String data = "example";
System.out.println(Cpt.decrypt(Cpt.crypt(data, key), key));
}
De sortie:
example
PHP...
function getEncrypt($sStr, $sKey) {
return base64_encode(
mcrypt_encrypt(
MCRYPT_RIJNDAEL_256,
$sKey,
$sStr,
MCRYPT_MODE_ECB
)
);
}
function getDecrypt($sStr, $sKey) {
return mcrypt_decrypt(
MCRYPT_RIJNDAEL_256,
$sKey,
base64_decode($sStr),
MCRYPT_MODE_ECB
);
}
En cours d'exécution:
$crypt = getDecrypt(getEncrypt($str, $key), $key);
echo "<p>Crypt: $crypt</p>";
De sortie:
Crypt: example�������������������������
À l'aide de PHP pour la crypte "exemple" avec la clé "Zvzpv8/PXbezPCZpxzQKzL/FeoPw68jIb+NONX/LIi8=" je "YTYhgp4zC+w5IsViTR5PUkHMX4i7JzvA6NJT1FqhoGy=".
À l'aide de Java à la crypte de la même chose avec la même clé, j'ai "+tdAZqTE7WAVPXhB3Tp5+g==".
Je suis d'encodage et de décodage en base64 dans le bon ordre, et je l'ai testé en base64 de coder et de décoder la compatibilité entre Java et PHP, et ça fonctionne.
source d'informationauteur LZZ
Vous devez vous connecter pour publier un commentaire.
BUG#1
MCRYPT_RIJNDAEL_256
n'est pas AES. 256 dans cette constante se réfère à la taille de bloc, pas la taille de la clé. UtilisationMCRYPT_RIJNDAEL_128
pour obtenir le même algorithme AES. La taille de la clé est définie seulement par le nombre d'octets dans l'argument-clé que vous fournissez. Afin d'approvisionnement de 32 octets et vous obtenez AES avec une clé de 256 bits.BUG#2
Ces deux lignes ne sont jamais corriger en Java et témoignent d'une méconnaissance fondamentale de la nature de l'arbitraire des données binaires produits par les transformations cryptographiques:
Il n'y a rien de mal à la transmission et au stockage
byte[]
directement, mais si vous devez utiliser uniquement imprimable chaînes, alors vous devriez base64 encode/decode pour le faire. Comme vous êtes déjà en utilisant base64 largement et qui semblent comme la voie à suivre. Je suppose que le bon deux lignes serait:EDIT:
Juste une blague à propos de bug #2. Vraiment, j'ai eu tort, je n'avais pas remarqué qu'il était le déchiffrer direction. Bien sûr, si vous connaissez la décrypté
byte[]
est une chaîne valide, alors il est parfaitement correct de faire ce que votre code ne.Je sais que c'est un vieux sujet, mais je vais ajouter ma solution de travail.
Que vous avez à réécrire PHP côté du script:
Vous devriez base64_decode($sKey) parce que votre clé est encodé en base64.
Ensuite, vous avez besoin pour créer cette fonction (le crédit va à beltrachi de http://www.php.net/manual/en/function.mcrypt-decrypt.php):
Utiliser ce code ne coder/décoder:
J'espère que ce sera utile pour quelqu'un! 🙂
Veuillez voir ici:
Différence en PHP cryptage d'iOS et .NET
AES Chiffrer en C#, décrypter en PHP
Le Cryptage en PHP et C#
Le problème auquel vous faites la rencontre d'un rembourrage. Je ne sais pas Java, mais
AES/ECB/PKCS5Padding
dirait que vous êtes en utilisant un fichier PKCS#5 (c'est essentiellement le même que le fichier PKCS#7) rembourrage tout en PHP natif uniquement en chargeNULL
-rembourrage. C'est ce que PKCS#5/7 n':Donc le code PHP pour faire de la marge de droite est trivial:
Garder à l'esprit pour avoir le même encodage pour les cordes. Essayez de convertir les chaînes de caractères dans les deux langues en UTF-8, par exemple, et de convertir des données binaires codées:
PHP (s). utf8_encode() fonction):
Java:
PHP, par exemple, ne doivent pas utiliser l'UTF-8 par défaut.