Skip to content

Commit

Permalink
Actually implement DES (a file is forgotten)
Browse files Browse the repository at this point in the history
  • Loading branch information
benallard committed Jul 22, 2011
1 parent b6bbdc4 commit 2213851
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 5 deletions.
6 changes: 6 additions & 0 deletions pythoncard/security/key.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ def _arrayTolong(bytes):
l += bytes[i]
return l

def _binaryToarray(bytes):
return [ord(c) for c in bytes]

def _arrayTobinary(array):
return ''.join([chr(i & 0xff) for i in array])

class Key(object):

def __init__(self, typ, size):
Expand Down
6 changes: 5 additions & 1 deletion pythoncard/security/keybuilder.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from pythoncard.security import publickey, privatekey
from pythoncard.security import publickey, privatekey, secretkey

class KeyBuilder(object):
LENGTH_AES_128 = 128
Expand Down Expand Up @@ -62,3 +62,7 @@ def buildKey(keyType, keyLength, keyEncryption):
return privatekey.PyCryptoRSAPrivateKey(keyLength)
elif keyType == KeyBuilder.TYPE_RSA_CRT_PRIVATE:
return privatekey.PyCryptoRSAPrivateKey(keyLength)
elif keyType in [KeyBuilder.TYPE_DES,
KeyBuilder.TYPE_DES_TRANSIENT_DESELECT,
KeyBuilder.TYPE_DES_TRANSIENT_RESET]:
return secretkey.pyDesDESKey(keyType, keyLength)
75 changes: 72 additions & 3 deletions pythoncardx/crypto/cipher.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,15 @@
from pythoncard.security import CryptoException, Key, RSAPrivateKey, \
RSAPrivateCrtKey, RSAPublicKey

from pythoncard.security.key import _arrayTolong, _longToArray
from pythoncard.security.secretkey import pyDesDESKey

from pythoncard.security.key import _arrayTolong, _longToArray, \
_arrayTobinary, _binaryToarray

try:
from pyDes import pyDes
except Importerror:
pyDes = None

class Cipher(object):

Expand Down Expand Up @@ -38,7 +46,7 @@ def getInstance(algorithm, shared):
Cipher.ALG_DES_ECB_PKCS5,
Cipher.ALG_DES_CBC_NOPAD,
Cipher.ALG_DES_CBC_PKCS5]:
return _PyCryptoDESCipher(algorithm)
return _pyDesDESCipher(algorithm)
print "algorithm not known: %d" % algorithm
raise CryptoException(CryptoException.NO_SUCH_ALGORITHM)

Expand Down Expand Up @@ -131,7 +139,68 @@ def doFinal(self, inBuff, inOffset, inLength, outBuff, outOffset):

return len(buf)

class _PyCryptoDESCipher(Cipher):
class _pyDesDESCipher(Cipher):

def __init__(self, algorithm):
if pyDes is None:
# shouldn't happen as it is included in pythoncard
raise CryptoException(CryptoException.NO_SUCH_ALGORITHM)
Cipher.__init__(self, algorithm)
self.desmode = {Cipher.ALG_DES_ECB_NOPAD: pyDes.ECB,
Cipher.ALG_DES_ECB_ISO9797_M1: pyDes.ECB,
Cipher.ALG_DES_ECB_ISO9797_M2: pyDes.ECB,
Cipher.ALG_DES_ECB_PKCS5: pyDes.ECB,
Cipher.ALG_DES_CBC_NOPAD: pyDes.CBC,
Cipher.ALG_DES_CBC_ISO9797_M1: pyDes.CBC,
Cipher.ALG_DES_CBC_ISO9797_M2: pyDes.CBC,
Cipher.ALG_DES_CBC_PKCS5: pyDes.CBC}[algorithm]
self.padmode = {Cipher.ALG_DES_ECB_NOPAD: pyDes.PAD_NORMAL,
Cipher.ALG_DES_ECB_ISO9797_M1: None,
Cipher.ALG_DES_ECB_ISO9797_M2: None,
Cipher.ALG_DES_ECB_PKCS5: pyDes.PAD_PKCS5,
Cipher.ALG_DES_CBC_NOPAD: pyDes.PAD_NORMAL,
Cipher.ALG_DES_CBC_ISO9797_M1: None,
Cipher.ALG_DES_CBC_ISO9797_M2: None,
Cipher.ALG_DES_CBC_PKCS5: pyDes.PAD_PKCS5}[algorithm]

def init(self, theKey, theMode, bArray = [0,0,0,0,0,0,0,0], bOff = 0, bLen = 8):
Cipher.init(self, theKey, theMode, bArray, bOff, bLen)

if not isinstance(theKey, pyDesDESKey):
raise CryptoException(CryptoException.ILLEGAL_VALUE)

if bLen != 8:
raise CryptoException(CryptoException.ILLEGAL_VALUE)

iv = [0 for i in xrange(8)]
Util.arrayCopy(bArray, bOff, iv, 0, bLen)

iv = _arrayTobinary(iv)

if 64 == theKey.getSize():
# DES
self._cipher = pyDes.des(theKey._key, self.desmode, iv,
padmode = self.padmode)
else:
#3DES
self._cipher = pyDes.triple_des(theKey._key, self.desmode, iv,
padmode = self.padmode)

self.initialized = True

def doFinal(self, inBuff, inOffset, inLength, outBuff, outOffset):
Cipher.doFinal(self, inBuff, inOffset, inLength, outBuff, outOffset)

data = [0 for i in xrange(inLength)]
Util.arrayCopy(inBuff, inOffset, data, 0, inLength)
data = _arrayTobinary(data)

if self.mode == Cipher.MODE_ENCRYPT:
result = self._cipher.encrypt(data)
else:
result = self._cipher.decrypt(data)

result = _binaryToarray(result)
Util.arrayCopy(result, 0, outBuff, outOffset, len(result))

return len(result)
17 changes: 16 additions & 1 deletion test/testCipher.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,19 @@ def GemaltoSample(self):

rsa.doFinal(buffer2encrypt, 0, 64, output_buffer, 0);


def testDES(self):

KeyArray = [1,2,3,4,5,6,7,8]
bytBuffer = [0 for i in xrange(8)]
MyBuffer = [7,5,6,8]

MyDesKey = KeyBuilder.buildKey(KeyBuilder.TYPE_DES, KeyBuilder.LENGTH_DES, False)
crypt_des = Cipher.getInstance(Cipher.ALG_DES_ECB_PKCS5, False)

MyDesKey.setKey(KeyArray, 0);
crypt_des.init(MyDesKey, Cipher.MODE_ENCRYPT);
length = crypt_des.doFinal(MyBuffer, 0, len(MyBuffer), bytBuffer, 0)
crypt_des.init(MyDesKey, Cipher.MODE_DECRYPT);
crypt_des.doFinal(bytBuffer, 0, length, MyBuffer, 0)

self.assertEquals([7,5,6,8], MyBuffer)

0 comments on commit 2213851

Please sign in to comment.