2016-12-07 2 views
0

J'ai le flux de travail suivant.Impossible de décrypter l'envoi blob par le serveur Java dans le client python

  1. Utilisez OpenSSL pour générer rsa keypair
  2. poste clé publique au serveur java
  3. constructions de serveur dans la mémoire clé publique
  4. serveur encrypte texte avec la clé publique et envoie blob retour
  5. Python déchiffre blob avec clé privée

Générer keypair public/privé:

openssl genrsa -out privkey.pem 1024 # generate private key 

openssl rsa -in privkey.pem -pubout > pubkey.pem # derive public key 

openssl pkcs8 -topk8 -in privkey.pem -outform PEM -inform PEM -nocrypt -out privkey.pkcs8 # convert private key to PKCS8 format 

code Python

import requests 
import base64 
from Crypto.PublicKey import RSA 

privkey_content = open('./keys/privkey.pkcs8', 'rb') 
pubkey_content = open('./keys/pubkey.pem', 'rb') 
priv_key = RSA.importKey(privkey_content.read()) 
pub_key = RSA.importKey(pubkey_content.read()) 
pubkey_der_content = pub_key.exportKey(format='DER') 
data = {'key' : base64.b64encode(pubkey_der_content)} 
resp = requests.post('http://localhost:9000/crypt/', data=data) 
decoded = priv_key.decrypt(base64.b64decode(resp.text)) 
with open('/tmp/decoded.txt', 'wb') as f: 
    f.write(decoded) 

code Java Server:

package com.hs.works; 

import org.apache.commons.codec.binary.Base64; 
import org.eclipse.jetty.http.HttpStatus; 

import javax.servlet.ServletException; 
import javax.servlet.http.HttpServlet; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 
import java.io.IOException; 
import java.security.interfaces.RSAPublicKey; 
import java.security.spec.X509EncodedKeySpec; 
import java.security.KeyFactory; 

import javax.crypto.Cipher; 

public class CryptServlet extends HttpServlet { 

    byte[] encrypt(byte[] pubKey, String text) { 
     try { 
      X509EncodedKeySpec keySpec = new X509EncodedKeySpec(pubKey); 
      KeyFactory keyFactory = KeyFactory.getInstance("RSA"); 
      RSAPublicKey k = (RSAPublicKey) keyFactory.generatePublic(keySpec); 
      final Cipher cipher = Cipher.getInstance("RSA"); 
      cipher.init(Cipher.ENCRYPT_MODE, k); 
      return cipher.doFinal(text.getBytes()); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
     return null; 
    } 

    @Override 
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
     String key = req.getParameter("key"); 
     byte[] decoded_bytes = Base64.decodeBase64(key.getBytes()); 
     byte[] encoded = encrypt(decoded_bytes, "SECRET_TEXT"); 
     resp.setStatus(HttpStatus.OK_200); 
     resp.getWriter().write(new String(Base64.encodeBase64(encoded))); 
    } 
} 

La sortie:

>>>f = open('/tmp/decoded.txt', 'rb') 
>>>c = f.read() 
>>> c 
'\x02bt\x1bq\xb1\x9bc\xef\xe30Q,o)<\xe8!z3B\xb7\xcf\xecWfN\x0f\x92~q\xb2\xcb\xa7\x15?%\xd1\xbf0$A,\x1ap?bZ$\xca6\xeet \xfc\x8d\x11\xee\n\x1b \xd3\xba\xaf\t\xf4&\x01\xa3\xb9H~\xd5o\x0c\xb3c\xa8\xdd\x9f4*\x86\x92\xe0\xcb\xb4\x1d\xcb\x9889\x856\xf9\xff\x9cGf\xf9\xa4\xc7\xadR\xb5\xcaU\xfc\xd355\xae\x87\x80\x1e\x00SECRET_TEXT' 
>>> 
>>> c[len(c) - 11:] 
'SECRET_TEXT' 

sur l'impression de la sortie du côté python, je vois SECRET_TEXT dans la sortie mais il y a aussi beaucoup de charabia avec ça.

Je ne suis pas sûr que ce soit lié au rembourrage ou à un autre problème.

Répondre

0

Je ne spécifiais pas le bon chiffre.

Fait suite à un changement dans le code du serveur:

final Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-1AndMGF1Padding"); 

et à la suite des changements dans le code client python:

from Crypto.Cipher import PKCS1_OAEP 
rsa_key = RSA.generate(2048) 
cipher = PKCS1_OAEP.new(rsa_key) 
pubkey = rsa_key.publickey() 
data = {'key' : base64.b64encode(pubkey.exportKey(format='DER'))} 
resp = requests.post('http://localhost:9000/crypt/', data=data) 
decoded = cipher.decrypt(base64.b64decode(resp.text))