2014-04-10 8 views
0

저는 일주일 동안 this을 사용하여 파이썬에있는 서버와 RSA 보안 통신을 구현했습니다.탄력성과 파이썬을 사용하는 자바 RSA 암호화 PKCS1-OAEP

그러나 나는 모든 병의 올바른 수입을 이해할 수 없다.

나는 탄력성 웹 사이트에서 발견되는 모든 항아리가 포함되어 있으며 주사위는 아직 없습니다!

나는 그들이 물건들을 움직 였다는 것을 읽었습니다. 이 코드가 오래되었거나 손상된 경우 pkcs1 패딩이있는 다른 RSA 구현이 있습니까?

편집 :

술집 키라는 이름의 파일 key.pub입니다.

enter image description here : 다음과 같은 오류가 대답

package Main; 


import org.bouncycastle.util.encoders.Base64; 

import javax.crypto.Cipher; 
import javax.xml.bind.DatatypeConverter; 
import java.io.*; 
import java.net.Socket; 
import java.net.UnknownHostException; 
import java.security.GeneralSecurityException; 
import java.security.KeyFactory; 
import java.security.PublicKey; 
import java.security.Security; 
import java.security.spec.X509EncodedKeySpec; 

public class EncDecRSA { 
    public static byte[] pemToDer(String pemKey) throws GeneralSecurityException { 
     String[] parts = pemKey.split("-----"); 
     return DatatypeConverter.parseBase64Binary(parts[parts.length/2]); 
    } 

    public static PublicKey derToPublicKey(byte[] asn1key) throws GeneralSecurityException { 
     X509EncodedKeySpec spec = new X509EncodedKeySpec(asn1key); 
     KeyFactory keyFactory = KeyFactory.getInstance("RSA", "BC"); 
     return keyFactory.generatePublic(spec); 
    } 

    public static byte[] encrypt(PublicKey publicKey, String text) throws GeneralSecurityException { 
     Cipher rsa = Cipher.getInstance("RSA/ECB/OAEPWithSHA1AndMGF1Padding", "BC");//PKCS1-OAEP 
     rsa.init(Cipher.ENCRYPT_MODE, publicKey); 
     byte[] cipher = rsa.doFinal(text.getBytes()); 
     String s = new String(cipher); 
     System.out.print(s); 
//  return cipher; 
//  return Base64.encode(rsa.doFinal(text.getBytes())); 
     cipher = Base64.encode(cipher); 
     return cipher; 

    } 

    static String readFile(String path) 
      throws IOException 
    { 
     String line = null; 
     BufferedReader br = new BufferedReader(new FileReader(path)); 
     try { 
      StringBuilder sb = new StringBuilder(); 
      line = br.readLine(); 

      while (line != null) { 
       sb.append(line); 
       sb.append("\n"); 
       line = br.readLine(); 
      } 
      return sb.toString(); 
     } finally { 
      br.close(); 

     } 

    } 
    public static void main(String[] args) throws IOException, GeneralSecurityException { 
     Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); 

     System.out.println("Working Directory = " + 
       System.getProperty("user.dir")); 
     String publicKey = readFile("key.public"); 
     byte[] pem = pemToDer(publicKey); 
     PublicKey myKey = derToPublicKey(pem); 
     String sendMessage = "{'vid_hash': '917ef7e7be4a84e279b74a257953307f1cff4a2e3d221e363ead528c6b556edb', 'state': 'ballot_response', 'userInfo': {'ssn': '700-33-6870', 'pin': '1234', 'vid': '265jMeges'}}"; 
     byte[] encryptedDATA = encrypt(myKey, sendMessage); 
     Socket smtpSocket = null; 
     DataOutputStream os = null; 
     DataInputStream is = null; 
     try { 
      smtpSocket = new Socket("192.168.1.124", 9999); 
      os = new DataOutputStream(smtpSocket.getOutputStream()); 
      is = new DataInputStream(smtpSocket.getInputStream()); 
     } catch (UnknownHostException e) { 
      System.err.println("Don't know about host: hostname"); 
     } catch (IOException e) { 
      System.err.println("Couldn't get I/O for the connection to: hostname"); 
     } 

     if (smtpSocket != null && os != null && is != null) { 
      try { 
       System.out.println("sending message"); 
       os.writeBytes(encryptedDATA+"\n"); 
       os.close(); 
       is.close(); 
       smtpSocket.close(); 
      } catch (UnknownHostException e) { 
       System.err.println("Trying to connect to unknown host: " + e); 
      } catch (IOException e) { 
       System.err.println("IOException: " + e); 
      } 
     } 
    } 
} 

를 기반으로 깨진 코드를 추가 : 어떻게에서 키

-----BEGIN PUBLIC KEY----- 
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv2B0wo+QJ6tCqeyTzhZ3 
AtPLgAHEQ/fRYDcR0BkQ+lXEhD277P2fPZwla5AW6szqsjR1olkZEF7IuoI27Hxm 
tQHJU0ROhrzstHgK42emz5Ya3BWcm+oq5pLDZnsNDnNlrPncaCT7gHQQJn3YjH8q 
aibtB1WCoy7ZJ127QxoKoLfeonBDtt7Qw6P5iXE57IbQ63oLq1EaYUfg8ZpADvJF 
b2H3MASJSSDrSDgrtCcKAUYuu3cZw16XShuKCNb5QLsj3tR0QC++7qjM3VcG311K 
7gHVjB6zybw+5vX2UWTgZuL6WVtCvRK+WY7nhL3cc5fmXZhkW1Jbx6wLPK3K/JcR 
NQIDAQAB 
-----END PUBLIC KEY----- 

편집 2로 사용되는 해당 파일을 읽고 있습니다

여기에 파이썬 코드가 있습니다 :

def _decrypt_RSA(self, private_key_loc, package): 
    ''' 
    param: public_key_loc Path to your private key 
    param: package String to be decrypted 
    return decrypted string 
    ''' 
    from Crypto.PublicKey import RSA 
    from Crypto.Cipher import PKCS1_OAEP 
    from base64 import b64decode 
    key = open('key.private', "r").read() 
    rsakey = RSA.importKey(key) 
    rsakey = PKCS1_OAEP.new(rsakey) 

    decrypted = rsakey.decrypt(package) 
    # decrypted = rsakey.decrypt(b64decode(package)) 
    return decrypted 

는 마지막 :

는 PKCS1-OAEP이 패딩 방식입니다.

이것이 작동하려면 이것이 주요 요구 사항입니다. 나는이 예제 모두 base64로 인코딩와

+0

Base64로 암호화 된 암호 텍스트를 피어에 보내고 암호 해독을 수행하기 전에 Base64로 암호 해독해야합니다. 결과 메시지는 256 바이트 여야하며 그렇지 않으면 암호 해독이 불평합니다. – divanov

답변

1

없이 시도

주 SpongyCastle입니다 - BouncyCastle의 안드로이드 리 패키지. 당신이 알아 차렸을 때 그들은 다릅니다. 그러나, 자바하게 암호화이

변환 Base64로

public static byte[] pemToDer(String pemKey) throws GeneralSecurityException { 
    String[] parts = pemKey.split("-----"); 
    return DatatypeConverter.parseBase64Binary(parts[parts.length/2]); 
} 

변환 ASN.1의 DER 인코딩 된 공개 키의 PublicKey 객체 ASN.1의 DER 인코딩 바이트 배열 키 문자열을 인코딩만큼이나 간단

public static PublicKey derToPublicKey(byte[] asn1key) throws GeneralSecurityException { 
    X509EncodedKeySpec spec = new X509EncodedKeySpec(asn1key); 
    KeyFactory keyFactory = KeyFactory.getInstance("RSA", "BC"); 
    return keyFactory.generatePublic(spec); 
} 

데이터 암호화

public static byte[] encrypt(PublicKey publicKey, String text) throws GeneralSecurityException { 
    Cipher rsa = Cipher.getInstance("RSA/ECB/OAEPWithSHA1AndMGF1Padding", "BC"); 
    rsa.init(Cipher.ENCRYPT_MODE, publicKey); 
    return rsa.doFinal(text.getBytes()); 
} 

bcprov-jdk15on-150.jar는 오직 용기가 필요 .

+0

코드를 수정 했습니까? 나는 fileopen과 read 호출을 사용하여 파일을 읽었지 만 암호화로 통과하지 못하게했다. – Cripto

+0

내 코드에 내 코드를 추가했다. 프로젝트 설정에 bcprov-jdk15on0150.jar을 추가했습니다. – Cripto

+0

RSA는 공개 키 모듈보다 긴 일반 텍스트를 암호화 할 수 없습니다. 게시 한 키는 256 바이트입니다.또한 OAEP 패딩에 42 바이트가 소비됩니다. 따라서 214 바이트를 넘지 않는 텍스트를 인코딩 할 수 있습니다. – divanov