2017-06-19 1 views
0

Comment puis-je envoyer les données d'un SecretKeySpec ou SecretKey de Java à PHP? Quand je le convertis en String (pour crypter avec RSA et publier en PHP), je reçois un diamant avec un point d'interrogation dedans.Comment envoyer une clé secrète de Java à PHP? (Utilisation de Android Studio et PhpStorm)

J'ai essayé d'utiliser utf8_decode mais ce problème est toujours présent.

EDIT:

I généré en PHP paire de clés RSA, et envoyé la clé publique à Java. En Java, je veux générer une AES_Key et crypter un texte en clair en utilisant AES, et envoyer un texte en clair crypté et AES_Key (qui est crypté avec RSA_Public_Key) de Java en PHP. Les codes suivants représentent les étapes de cryptage/décryptage AES de ce projet:

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); 
    } 
} 
?> 

Création d'un secretKey (comme la clé AES), le chiffrement du texte brut (nom) par clé AES, crypter clé AES, et les préparer pour l'envoi à 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); 

code PHP pour décrypter la clé AES à l'aide de la clé AES par décryptée clé privée RSA et le déchiffrement du nameString:

$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); 
  1. ces classes sont-correspondance entre eux?

  2. Comment crypter un texte en clair à l'aide de la clé AES (ou d'une copie d'une clé secrète générée en Java)? Comment décrypter un texte en clair à l'aide de la clé AES (qui est déchiffrée par RSA Private Key)?

+0

Il n'y a pas de code dans votre question. Vous devriez changer cela. En outre, vous n'envoyez pas de données d'un IDE à l'autre. Un IDE est juste un véhicule pour écrire du code. Il n'héberge pas le service. Enfin, avez-vous entendu parler de l'encodage Base64? –

+0

@ArtjomB. Peut-être qu'il essaie de mettre la même clé dans les deux plates-formes à des fins de débogage. –

+0

Que voulez-vous dire par "pour le cryptage RSA"? –

Répondre

1

Une clé secrète est constituée d'octets aléatoires. Cela signifie que, quel que soit le codage utilisé, certains octets ne s'imprimeront pas. Pour représenter les octets comme du texte, vous utilisez généralement un codage hexadécimal ou base64. La différence entre ces deux est qu'une personne normale peut distinguer les valeurs d'octets des hexadécimaux tandis que base64 est plus efficace (car elle utilise plus de caractères et peut donc coder 6 bits par caractère où les hexadécimaux n'encodent que 4 bits par caractère).

Dans Java 8 seule base 64 est pris en charge par défaut:

System.out.println(Base64.getEncoder().encodeToString(secretKey.getEncoded())); 

et pour Android:

Base64.encodeToString(secretKey.getEncoded(),Base64.DEFAULT); 

devrait fonctionner correctement (pour SecretKeySpec aussi bien, car il met en œuvre SecretKey).


Bien sûr, l'envoi d'une clé secrète sans protection doit être effectuée dans un environnement sécurisé et devrait en général être évités à tout prix.

+0

Merci, mais j'ai une question. Quelle est la différence entre: Base64.getEncoder(). EncodeToString (secretKey.getEncoded()) et Base64.encodeToString (secretKey.getEncoded(), Base64.DEFAULT) – Yousef

+0

Rien vraiment, l'un est pour Java, un pour Android. –

+0

Si j'envoie la chaîne utilisée par Base64.encodeToString (secretKey.getEncoded(), Base64.DEFAULT) à PHP, comment puis-je accéder à cette clé secrète pour l'utiliser comme clé AES pour déchiffrer un texte en PHP. J'ai essayé d'utiliser "base64_decode (avec/sans) hex2bin_function", mais il renvoie une chaîne différente. J'apprécie si vous m'aidez avec un lien approprié et utile, lié à lui. (AES décryptin en PHP en utilisant la clé reçue de Java) – Yousef