2012-05-31 3 views
3

에 의해 인코딩 다음의 암호를 해독하는 방법 그러나복어 암호 해독 내가 thefollowing 한, <a href="https://raw.github.com/usefulfor/usefulfor/master/security/JBoss.java" rel="nofollow">https://raw.github.com/usefulfor/usefulfor/master/security/JBoss.java</a>에서 발견 된 코드를 사용 javax.crypto의

bash-3.2$ java -cp . JBoss -e testpython 
-27038292d345798947e2852756afcf0a 
bash-3.2$ java -cp . JBoss -d -27038292d345798947e2852756afcf0a 
testpython 

을, 나는 내 인생에 대한 알아낼 수 없습니다 문자열 '27038292d345798947e2852756afcf0a'파이썬에서 pycrypto 사용. Java 코드가 Blowfish를 사용하고 있고 'jaas가 암호'의 열쇠 인 방식이라고 생각합니다. 그러나 나는 파이썬에서 이것을하는 법을 전혀 알지 못한다. 다음은 대부분 인쇄 할 수없는 쓰레기의 결과입니다.

import Crypto 
from Crypto.Cipher import Blowfish 
from base64 import b64encode, b64decode 

bs  = Blowfish.block_size 
key  = 'jaas is the way' 
plaintext = b'27038292d345798947e2852756afcf0a' 
iv  = '\0' * 8 

c1 = Blowfish.new(key, Blowfish.MODE_ECB) 
c2 = Blowfish.new(key, Blowfish.MODE_CBC, iv) 
c3 = Blowfish.new(key, Blowfish.MODE_CFB, iv) 
c4 = Blowfish.new(key, Blowfish.MODE_OFB, iv) 

msg1 = c1.decrypt(plaintext) 
msg2 = c2.decrypt(plaintext) 
msg3 = c3.decrypt(plaintext) 
msg4 = c4.decrypt(plaintext) 

print "msg1 = %s\n" % msg1 
print "msg2 = %s\n" % msg2 
print "msg3 = %s\n" % msg3 
print "msg4 = %s\n" % msg4 

무엇이 누락 되었습니까?

감사합니다.

+0

더에 오신 것을 환영합니다 SO를하는 데 도움이! 답변 옆에있는 확인란을 사용하여 답변을 수락 된 것으로 표시하십시오. – jterrace

답변

5

우선 Java 예제 코드는 매우 나쁩니다. 암호문은 정수로 출력되지만 암호문은 이진 문자열로 남겨 두어야합니다. 이유는 정수가 무한대의 이진 인코딩으로 표현 될 수 있기 때문입니다. 예를 들어, 숫자 1은 '0x01'(1 바이트), '0x0001'(2 바이트) 등이 될 수 있습니다. 암호화 기능을 다루는 경우 표현과 관련하여 매우 정확해야합니다.

또한이 예에서는 javax.crypto API의 기본값을 사용하며 어디에도 설명되어 있지 않습니다. 그래서 그것은 정말로 시행 착오입니다.

해결 방법은 how to convert negative integers to hex strings in Python입니다. 이 경우 16 진수 문자열은 필요 없지만 바이트 표현은 필요합니다. 그러나 개념은 동일합니다. 저는 PyCrypto의 long_to_bytes을 사용하여 (임의 길이의) 양의 정수를 바이트 문자열로 변환합니다.

from Crypto.Cipher import Blowfish 
from Crypto.Util.number import long_to_bytes 

def tobytestring(val, nbits): 
    """Convert an integer (val, even negative) to its byte string representation. 
    Parameter nbits is the length of the desired byte string (in bits). 
    """ 
    return long_to_bytes((val + (1 << nbits)) % (1 << nbits), nbits/8) 

key = b'jaas is the way' 
c1 = Blowfish.new(key, Blowfish.MODE_ECB) 

fromjava = b"-27038292d345798947e2852756afcf0a" 
# We don't know the real length of the ciphertext, assume it is 16 bytes 
ciphertext = tobytestring(int(fromjava, 16), 16*8) 
print c1.decrypt(ciphertext) 

출력은 다음과 같습니다 당신이 javax.crypto은 또한 당신이 직접 제거 할 필요가 PKCS # 5 패딩을 추가 것을 볼 것을에서

'testpython\x06\x06\x06\x06\x06\x06' 

. 그것은 할 사소한 일입니다.

그러나 문제의 해결책은 더 나은 방법으로 Java 암호화를 수행하는 것입니다. 파이썬 코드는 크게 단순화 될 것입니다.

+0

+1 좋은 일을 알아 냈어. 음수 16 진수 값을 BigInteger와 같은 바이트 배열로 변환하는 방법을 알아 내려고 노력했습니다. Java 코드가 암호문을 인쇄하는 끔찍한 방법이라고 동의 함 – jterrace

+0

@jterrace이 대답을 수락하면 왼쪽의 큰 흰색 "V"를 클릭하십시오. – SquareRootOfTwentyThree

+0

나는 OP가 아니다 :) (또한 체크 마크가 V가 아니다) – jterrace

0

이 나에게

private byte[] encrypt(String key, String plainText) throws GeneralSecurityException { 

    SecretKey secret_key = new SecretKeySpec(key.getBytes(), ALGORITM); 

    Cipher cipher = Cipher.getInstance(ALGORITM); 
    cipher.init(Cipher.ENCRYPT_MODE, secret_key); 

    return cipher.doFinal(plainText.getBytes()); 
} 

이 당신을 위해 도움이 될 것입니다 희망, http://dexxtr.com/post/57145943236/blowfish-encrypt-and-decrypt-in-java-android