PageRenderTime 47ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/local/src.zip/util/crypto.py

https://code.google.com/p/wallproxy-plugins/
Python | 130 lines | 124 code | 4 blank | 2 comment | 2 complexity | be23c22bb599dbd64800be7e97c30fca MD5 | raw file
  1. # Copyright (C) 2010-2011 | GNU GPLv3
  2. __author__ = '%s & %s' % ('d3d3LmVodXN0QGdtYWlsLmNvbQ=='.decode('base64'),
  3. 'YnJvbnplMW1hbkBnbWFpbC5jb20='.decode('base64'))
  4. import hashlib, itertools
  5. __all__ = ['Crypto']
  6. class XOR:
  7. '''XOR with pure Python in case no PyCrypto'''
  8. def __init__(self, key):
  9. self.key = key
  10. def encrypt(self, data):
  11. xorsize = 1024
  12. key = itertools.cycle(map(ord, self.key))
  13. dr = xrange(0, len(data), xorsize)
  14. ss = [None] * len(dr)
  15. for i,j in enumerate(dr):
  16. dd = [ord(d)^k for d,k in itertools.izip(data[j:j+xorsize], key)]
  17. ss[i] = ''.join(map(chr, dd))
  18. return ''.join(ss)
  19. decrypt = encrypt
  20. class NUL:
  21. def encrypt(self, data):
  22. return data
  23. decrypt = encrypt
  24. class Crypto:
  25. _BlockSize = {'AES':16, 'ARC2':8, 'ARC4':1, 'Blowfish':8, 'CAST':8,
  26. 'DES':8, 'DES3':8, 'IDEA':8, 'RC5':8, 'XOR':1}
  27. _Modes = ['ECB', 'CBC', 'CFB', 'OFB', 'PGP'] #CTR needs 4 args
  28. _KeySize = {'AES':[16,24,32], 'CAST':xrange(5,17),
  29. 'DES':[8], 'DES3':[16,24], 'IDEA':[16]}
  30. def __init__(self, mode='AES-CBC-32'):
  31. mode = mode.split('-')
  32. mode += [''] * (3 - len(mode))
  33. #check cipher
  34. self.cipher = mode[0] if mode[0] else 'AES'
  35. if self.cipher not in self._BlockSize:
  36. raise ValueError('Invalid cipher: '+self.cipher)
  37. #check ciphermode
  38. if self._BlockSize[self.cipher] == 1:
  39. self.ciphermode = ''
  40. else:
  41. self.ciphermode = mode[1] if mode[1] in self._Modes else 'CBC'
  42. #check keysize
  43. try:
  44. self.keysize = int(mode[2])
  45. except ValueError:
  46. self.keysize = 32
  47. if self.keysize != 0:
  48. if self.cipher in self._KeySize:
  49. keysize = self._KeySize[self.cipher]
  50. if self.keysize not in keysize:
  51. self.keysize = keysize[-1]
  52. #avoid Memmory Error
  53. if self.cipher=='RC5' and self.keysize in (1, 57): self.keysize=32
  54. #try to import Crypto.Cipher.xxxx
  55. try:
  56. cipherlib = __import__('Crypto.Cipher.'+self.cipher, fromlist='x')
  57. self._newobj = cipherlib.new
  58. if self._BlockSize[self.cipher] != 1:
  59. self._ciphermode = getattr(cipherlib, 'MODE_'+self.ciphermode)
  60. except ImportError:
  61. if self.cipher == 'XOR': self._newobj = XOR
  62. else: raise
  63. def paddata(self, data):
  64. blocksize = self._BlockSize[self.cipher]
  65. if blocksize != 1:
  66. padlen = (blocksize - len(data) - 1) % blocksize
  67. data = '%s%s%s' % (chr(padlen), ' '*padlen, data)
  68. return data
  69. def unpaddata(self, data):
  70. if self._BlockSize[self.cipher] != 1:
  71. padlen = ord(data[0])
  72. data = data[padlen+1:]
  73. return data
  74. def getcrypto(self, key):
  75. if self.keysize==0 and key=='':
  76. return NUL()
  77. khash = hashlib.sha512(key).digest()
  78. if self.keysize != 0:
  79. key = khash[:self.keysize]
  80. blocksize = self._BlockSize[self.cipher]
  81. if blocksize == 1:
  82. return self._newobj(key)
  83. return self._newobj(key, self._ciphermode, khash[-blocksize:])
  84. def encrypt(self, data, key):
  85. crypto = self.getcrypto(key)
  86. data = self.paddata(data)
  87. return crypto.encrypt(data)
  88. def decrypt(self, data, key):
  89. crypto = self.getcrypto(key)
  90. data = crypto.decrypt(data)
  91. return self.unpaddata(data)
  92. def getmode(self):
  93. return '%s-%s-%d' % (self.cipher, self.ciphermode, self.keysize)
  94. def __str__(self):
  95. return '%s("%s")' % (self.__class__, self.getmode())
  96. def getsize(self, size):
  97. blocksize = self._BlockSize[self.cipher]
  98. return (size + blocksize - 1) // blocksize * blocksize
  99. class Crypto2(Crypto):
  100. def paddata(self, data):
  101. blocksize = self._BlockSize[self.cipher]
  102. if blocksize != 1:
  103. padlen = (blocksize - len(data) - 1) % blocksize
  104. data = '%s%s%s' % (data, ' '*padlen, chr(padlen))
  105. return data
  106. def unpaddata(self, data):
  107. if self._BlockSize[self.cipher] != 1:
  108. padlen = ord(data[-1])
  109. data = data[:-(padlen+1)]
  110. return data