2016-07-03 11 views
1

Einige Hintergrund von dem, was ich versuche zu erreichen.Wie repliziert man Java-Verschlüsselung in PHP?

Part 1.

PHP-Server kommuniziert mit einem Java-basierten Gerät. PHP verwendet OpenSSL zum Generieren eines öffentlichen/privaten Schlüsselpaars und sendet dann den öffentlichen Schlüssel an das Gerät, das wiederum eine verschlüsselte macKey (generiert mit dem öffentlichen Schlüssel) zurückgibt, die in base64 codiert ist. PHP muss nun die macKey mit dem privaten Schlüssel base64-decodieren und entschlüsseln.

Was entspricht dem folgenden Java Code-Snippet in PHP?

String base64EncodedMacKey = "LkvTT9LFj5lcxRRB8KrwwN906fSIDDcJvQK3E7a5PbR+Ox9WnslOs32jSCC9FkE8ouvr2MfWwtppuZmoPjaxwg3yAQI4UN3T1loISuF2VwKWfJ45fywbK9bNnD5Cw7336mjoGctv77Tg3JXPrsRwgMGIlBsNwdt1B0wgT4MMMAjl32TnBI3iwQ94VTMHffrK+QToddTahRHHoVsr3FVrETdiqKXdkiX1jES53im5lrXYIsY89UFkGzPo+3u4ijKIQWSLvYnA5wXI128gFHKxKYS82MbJDUn9i1RVFsGaP6T3nQRSX5SZNpSe5yGFWwMgYOx0KXMgET82FeaL2hfWuw=="; 
byte[] base64DecodedMacKey = DatatypeConverter.parseBase64Binary(base64EncodedMacKey); 

Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); 
cipher.init(Cipher.DECRYPT_MODE, keypair.getPrivate()); 

byte[] macKey = cipher.doFinal(base64DecodedMacKey); 

Hier ist, was ich in PHP versucht, aber ich bin verwirrt über die Verwendung von im Vergleich zu String-Byte-Array, wenn die macKey

Entschlüsseln
$macKey = 'LkvTT9LFj5lcxRRB8KrwwN906fSIDDcJvQK3E7a5PbR+Ox9WnslOs32jSCC9FkE8ouvr2MfWwtppuZmoPjaxwg3yAQI4UN3T1loISuF2VwKWfJ45fywbK9bNnD5Cw7336mjoGctv77Tg3JXPrsRwgMGIlBsNwdt1B0wgT4MMMAjl32TnBI3iwQ94VTMHffrK+QToddTahRHHoVsr3FVrETdiqKXdkiX1jES53im5lrXYIsY89UFkGzPo+3u4ijKIQWSLvYnA5wXI128gFHKxKYS82MbJDUn9i1RVFsGaP6T3nQRSX5SZNpSe5yGFWwMgYOx0KXMgET82FeaL2hfWuw=='; 
$base64DecodedMacKey = base64_decode($macKey); 
openssl_private_decrypt($base64DecodedMacKey, $decrypted, $privateKey); 

Die $decrypted oben hält einige binäre Daten, wie es scheint, so dass ich m nicht sicher, ob ich es in ein Byte-Array konvertieren müssen oder es als String zu behandeln ...


Teil 2.

Jede Anfrage hat eine counter. Der macKey in Java-Code oben wird verwendet, um einen MAC-Wert aus counter zu erstellen.

Was entspricht dem folgenden Java Code-Snippet in PHP?

int counter = 0; 
String nextCounter = String.valueOf(++counter); 
SecretKeySpec signingKey = new SecretKeySpec(macKey, "AES"); 
Mac mac = Mac.getInstance("HmacSHA256"); 
mac.init(signingKey); 
byte[] counterMac = mac.doFinal(nextCounter.getBytes("UTF-8")); 
String base64EncodedMac = DatatypeConverter.printBase64Binary(counterMac); 

The base64EncodedMac oben wird schließlich an das Gerät gesendet Kommunikation zu validieren.

Ich habe versucht, verschiedene Lösungen zu googeln, aber ich war nicht erfolgreich in der Generierung einer gültigen base64EncodedMac Zeichenfolge in PHP für das Gerät, um es zu genehmigen.

Antwort

0

Die Lösung selbst gefunden. Für Teil 1 wählte ich phpseclib, um die öffentlichen/privaten Schlüssel zu generieren und den Verschlüsselungsalgorithmus anzugeben. Entschlüsseln macKey:

$rsa = new Crypt_RSA(); 
$keys = $rsa->createKey(2048); 
// [...] 

$macKey = base64_decode($base64EncodedMacKey); 

$rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1); 
$rsa->loadKey($keys['privatekey']); 
$decryptedMac = $rsa->decrypt($macKey); 

Gefolgt von Teil 2:

$counter = 0; 
$hmac = hash_hmac('sha256', ++$counter, $decryptedMac, true); 
$counterMac = base64_encode($hmac); 

Der Haupt wurde verwirrender Teil, dass in Java, HMAC wurde aus Byte-Array durchgeführt, während in PHP die hash_hmac Funktion als einen String erwartet 2. Parameter, also unpack() war nicht ausreichend. Es scheint jedoch mit der $counter direkt bestanden zu haben. Es war auch wichtig, den vierten Parameter als TRUE zu verwenden, um Rohdaten zurückzugeben.

Verwandte Themen