Showing posts with label python. Show all posts
Showing posts with label python. Show all posts

Python SocksiPy Global Setting edit

SocksiPy?

This module was designed to allow developers of Python software that uses the Internet or another TCP/IP-based network to add support for connection through a SOCKS proxy server with as much ease as possible.

Global Setting for urllib2 Example

You can use SocksiPy module. Simply copy the file "socks.py" to your Python's lib/site-packages directory, and you're ready to go. you must use socks before urllib2. For example:
import socks
import socket
socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5, "127.0.0.1", 8080)
socket.socket = socks.socksocket
import urllib2
print urllib2.urlopen('http://www.google.com').read()
You can also try pycurl lib and tsocks, for more detail, click on here.

TypeError: listdir() argument 1 must be (buffer overflow), not str edit

Can you please explain what specifically you consider a bug here? I can see that the error message is confusing, so it could be improved. However, there is nothing we can do to make the error go away. The Microsoft C library simply does not support file names longer than MAX_PATH; you have to use Unicode file names to go beyond this limit.

PKCS Padding Method edit

PKCS 패딩이란 PKCS 산업 표준에서 권고하는 표준 패딩 방법이며, 이곳에 가면 더 많은 패딩 방법들을 볼 수 있다.

패딩을 내부에서 처리해주지 않는 PyCryptoAES와 같은 블럭 암호 알고리즘을 사용할때에는 패딩을 직접 구현해야 한다. 하지만 M2Crypto를 사용하면 모듈이 다 알아서 해준다.

Thankfully, there's another options: Me Too Crypto. Unlike PyCrypto, M2Crypto is a Python wrapper around OpenSSL which is nice, as my code will be running under mod_wsgi embedded in Apache along with mod_ssl.

PKCS 표준 패딩 규칙

The rules for PKCS padding are very simple:
  • Padding bytes are always added to the clear text before it is encrypted.
  • Each padding byte has a value equal to the total number of padding bytes that are added. For example, if 6 padding bytes must be added, each of those bytes will have the value 0x06.
  • The total number of padding bytes is at least one, and is the number that is required in order to bring the data length up to a multiple of the cipher algorithm block size.

  • 패딩은 무조건(always) 추가되어야 한다.
  • 각 패딩은 전체 패딩 바이트 크기 값을 가진다. (6개의 패딩 추가시 각 패딩의 값은 0x06)
  • 총 패딩의 크기는 최소한 1바이트이며 평문의 길이를 암호 알고리즘의 블럭 크기의 배수만큼 맞춰주기위한 크기가 된다.

RFC 2315 (PKCS #7: Crytographic Message Syntax)를 참조하자면

Some content-encryption algorithms assume the input length is a multiple of k octets, where k > 1, and let the application define a method for handling inputs whose lengths are not a multiple of k octets. For such algorithms, the method shall be to pad the input at the trailing end with k - (l mod k) octets all having value k - (l mod k), where l is the length of the input. In other words, the input is padded at the trailing end with one of the following strings: 01 -- if l mod k = k-1 02 02 -- if l mod k = k-2 . . . k k ... k k -- if l mod k = 0

이렇듯 패딩이 필요하지 않은(l mod k == 0) 마지막 부분에도 무조건(always) 패딩을 추가하는것을 볼 수 있다. 이때 패딩의 개수는 블럭 알고리즘의 블록 크기가 된다.

예시

EXAMPLE 1 Clear text consists of the following18 bytes: F14ADBDA019D6DB7 EFD91546E3FF8444 9BCB In order to make this a multiple of 16 bytes (the AES block size), we must add 14 bytes. Each byte will contain the value 0x0E, which is 14, the total number of padding bytes added. The result is that the padded clear text is as follows: F14ADBDA019D6DB7 EFD91546E3FF8444 9BCB0E0E0E0E0E0E 0E0E0E0E0E0E0E0E The padded value is 32 bytes in length, which is two AES blocks. This padded string is encrypted in CBC mode, and the resulting ciphertext will also be 32 bytes in length. EXAMPLE 1 Clear text consists of the following16 bytes: 971ACD01C9C7ADEA CC83257926F490FF This is already a multiple of the AES block size, but PKCS padding rules say that padding is always applied. Thus, we add 16 bytes of padding to bring the total length to 32, the next multiple of the AES block size. Each pad byte has the value 0x10, which is 16, the total number of padding bytes added. The result is that the padded clear text is as follows: 971ACD01C9C7ADEA CC83257926F490FF 1010101010101010 1010101010101010 The padded value is 32 bytes in length, which is two AES blocks. This padded string is encrypted in CBC mode, and the resulting cipher text will also be 32 bytes in length.

왠지 낭비인것 같지만 표준이 그러니 표준을 따르자면 표준대로 해야겠다.

표준과의 관계

Note that the PKCS standards that define this padding method describe it in a way that limits the maximum padding length to 8 bytes. This is a consequence of the fact that the algorithms at that time used 8-byte blocks. We extend the definition to apply to 16-byte AES cipher blocks.

PKCS 표준에는 패딩의 최대크기가 8바이트이다. 이것은 해당 표준이 제정된 시기에는 블록 알고리즘들의 블록크기가 8바이트였기 때문이다. AES에 적용하기 위해 16바이트로 확장한다.

결국 패딩 방법은 입맛에 맞게 쓰면 되는것 같다.

PKCS#5와 PKCS#7

PKCS#5 padding and PKCS#7 padding are the same (adding bytes 01, or 0202, or 0303 etc up to the length of the block size of the algorithm, 16 bytes in this case).

Method 1 - Pad with bytes all of the same value as the number of padding bytes This is the method recommended in [PKCS5], [PKCS7], and [CMS].

다른 문서에서 같은 메쏘드를 권고하는것 같다.

Python에서 구현하기

pad = lambda s: s + (16 - len(s) % 16) * chr(16 - len(s) % 16)
unpad = lambda s: s[0:-ord(s[-1])]

16은 블럭 알고리즘의 한 블럭의 크기이며 AES사용시 블럭크기가 16이다.

직접 구현해서 테스트해보았다.

import sys

def pad(s):
    pad = 16 - (len(s) % 16)
    pad = chr(pad) * pad
    print 'PADDING:\t', len(pad), [pad]
    return s + pad

def unpad(s):
    i = 1
    print 'PADSIZE:\t', ord(s[-1])
    while i < ord(s[-1]):
        if s[-i] != s[-1]:
            print 'WARNING'
            break
        i += 1
    print 'DATAEND:\t', len(s) - i
    return s[:-i]

print
data = sys.argv[1]
print 'ORIGINAL:\t', len(data), data

padded = pad(data)
print 'PADDED:\t\t', len(padded), [padded]

unpadded = unpad(padded)
print 'UNPADDED:\t', len(unpadded), [unpadded]
print
print unpadded == data
$ python aesfile.py apsdbua0w934bawklbamf.basnbl3wn4balk34bals125

ORIGINAL:       45 apsdbua0w934bawklbamf.basnbl3wn4balk34bals125
PADDING:        3 ['\x03\x03\x03']
PADDED:         48 ['apsdbua0w934bawklbamf.basnbl3wn4balk34bals125\x03\x03\x03']
PADSIZE:        3
DATAEND:        45
UNPADDED:       45 ['apsdbua0w934bawklbamf.basnbl3wn4balk34bals125']

True

$ python aesfile.py apsdbua0w934bawklbamf.basnbl3wn4balk34bals123456

ORIGINAL:       48 apsdbua0w934bawklbamf.basnbl3wn4balk34bals123456
PADDING:        16 ['\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10']
PADDED:         64 ['apsdbua0w934bawklbamf.basnbl3wn4balk34bals123456\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10']
PADSIZE:        16
DATAEND:        48
UNPADDED:       48 ['apsdbua0w934bawklbamf.basnbl3wn4balk34bals123456']

True

언패딩 방법이 상당히 집요한데 뒤에서부터 앞으로 마지막 패딩값만큼 반복하면서 자료의 끝(패딩의 시작점 - 1)을 구한다음 짤라 출력한다. 중간에 값이 마지막 패딩값과 다르면 패딩이 잘못 추가된 것이므로 에러(WARNING)을 출력하고 루프를 빠져나온다. 하지만 궂이 이렇게까지 해야할까 하는 의문이 드는데 어차피 마지막 패딩부분에서만 연산하기때문에 속도는 문제될것이 없지만 나중에 잘 구현된 알고리즘을 참고하거나 패딩부분이 구현된 모듈을 써야겠다.

Convert string to hex (Python recipe) edit

encode and decode. this functionality already exists with the encodings library (which is built-in):
>>> "hello".encode("hex")
'68656c6c6f'
>>> "68656c6c6f".decode("hex")
'hello'
>>>

PyCrypto 윈도우즈 환경에서 컴파일하기 edit

PyCrypto는 파이썬 암호화 툴킷이다.

MinGW 설치

C로 작성된 소스들을 컴파일하기위해 MinGW를 설치하였고 설치도중 MSYS 설치해야 autoconf 에러가 안난다.

MSYS is a collection of GNU utilities such as bash, make, gawk and grep to allow building of applications and programs which depend on traditionally UNIX tools to be present. It is intended to supplement MinGW and the deficiencies of the cmd shell.

시스템 환경 변수 수정

설치 이후 환경 변수(컴퓨터 > 고급 시스템 설정 > 고급 탭 > 환경 변수)의 시스템 변수 Path에 아래 경로를 새로 추가해준다. ';'는 경로들을 구분짓기위한 문자이다.

;C:\MinGW\bin;C:\MinGW\msys\1.0\bin

만약 바로 적용이 안된다면 시스템을 재부팅 하거나 레지스트리 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\EnvironmentPath값을 직접 수정한다.

빌드(설치) 하기

컴파일러 옵션 없이 setup.py를 실행하면 vcvarsall.bat를 찾을 수 없다는 에러가 난다. 옵션 --compiler=mingw32를 붙여준다.

python setup.py install --compiler=mingw32

gcc: error: unrecognized command line option '-mno-cygwin'

컴파일 도중 위와 같은 에러가 난다면 C:\python2.x\distutils\cygwinccompiler.py를 직접 수정하여 -mno-cygwin를 찾아 바꿔 모조리 지워버린다.

It sounds like GCC 4.7.0 has finally removed the deprecated -mno-cygwin option, but distutils has not yet caught up with it. Either install a slightly older version of MinGW, or edit distutils\cygwinccompiler.py in your Python directory to remove all instances of -mno-cygwin.

-mno-cygwin옵션은 더이상 사용되지 않는 옵션이며 파이썬 버그리포트 참조.

Python handling exceptions edit

http://docs.python.org/tutorial/errors.html#handling-exceptions

def divide(x, y):
    r = 0
    while r < 3:
        try:
            result = x / y
        except ZeroDivisionError:
            print "division by zero!"
            r += 1
            continue
        else:
            print "result is", result
            return 'haha'
        finally:
            print "executing finally clause"
    return "end"

print divide(2, 3)

위의 예외 구문에서 예외가 발생하지 않을때 return을 한다.

문제는 과연 finally:~ 구문을 실행할까?

result is 0
executing finally clause
haha

return 이전에 finally 구문을 실행하고 return 된다.

Python metaWeblog upload a file using newMediaObject edit

파일을 읽은 이진데이터를 구조체안에 넣을때 xmlrpclib.Binary()를 써야한다.

import xmlrpclib
import mimetypes

USERID = "userid"
PASSWORD = "password"
BLOGID = 123456 # API KEY
URL = "http://yourblog.com/api"

mw = xmlrpclib.ServerProxy(URL).metaWeblog

# Open file
fp = open("test.jpg", "rb")

# Upload image
url = mw.newMediaObject(BLOGID, USERID, PASSWORD,
                {"name": fp.name, "type": mimetypes.guess_type(fp.name)[0],
                "bits": xmlrpclib.Binary(fp.read())})["url"]

print url
<- Older