1 #!/usr/bin/env python
2
3 '''
4
5 Python Crypto Wrapper - By Chase Schultz
6
7 Currently Supports: AES-256, RSA Public Key, RSA Signing, ECC Public Key, ECC Signing
8
9 Dependencies: pyCrypto - https://github.com/dlitz/pycrypto
10 PyECC - https://github.com/rtyler/PyECC
11
12
13 Python Cryptography Wrapper based on pyCrypto
14 Copyright (C) 2011 Chase Schultz - chaschul@uat.edu
15
16 This program is free software: you can redistribute it and/or modify
17 it under the terms of the GNU General Public License as published by
18 the Free Software Foundation, either version 3 of the License, or
19 (at your option) any later version.
20
21 This program is distributed in the hope that it will be useful,
22 but WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 GNU General Public License for more details.
25
26 You should have received a copy of the GNU General Public License
27 along with this program. If not, see <http://www.gnu.org/licenses/>.
28
29
30 '''
31
32 __author__ = 'Chase Schultz'
33 __version__ = '0.1'
34
35 import os
36 import base64
37 from Crypto.Cipher import AES
38 from Crypto.PublicKey import RSA
39 from Crypto.Hash import SHA256
40 from pyecc import ECC
41
42 class CryptoWrapper():
43
44 '''AES Cipher Specifics'''
45 blockSize = 16 #Block Size
46 keySize = 32 #keySize in Bytes - 32 bytes = 256bit Encryption
47 mode = AES.MODE_CBC #Cipher Block Mode
48
49 def __init__(self):
50
51 pass
52
53 def __generateAESKeystring__(self):
54 '''Generates Pseudo Random AES Key and Base64 Encodes Key - Returns AES Key'''
55 key = os.urandom(self.keySize)
56 keyString = base64.urlsafe_b64encode(str(key))
57 return keyString
58
59 def __extractAESKey__(self, keyString):
60 '''Extracts Key from Base64 Encoding'''
61 key = base64.urlsafe_b64decode(keyString)
62 if len(key) != self.keySize:
63 raise Exception('Error: Key Invalid')
64 os._exit(1)
65 return key
66
67 def __extractCrypto__(self, encryptedContent):
68 '''Decodes Base64 Encoded Crypto'''
69 cipherText = base64.urlsafe_b64decode(encryptedContent)
70 return cipherText
71
72 def __encodeCrypto__(self, encryptedContent):
73 '''Encodes Crypto with Base64'''
74 encodedCrypto = base64.urlsafe_b64encode(str(encryptedContent))
75 return encodedCrypto
76
77 def aesEncrypt(self, data):
78 '''Encrypts Data w/ pseudo randomly generated key and base64 encodes cipher - Returns Encrypted Content and AES Key'''
79 key = self.__generateAESKeystring__()
80 encryptionKey = self.__extractAESKey__(key)
81 pad = self.blockSize - len(data) % self.blockSize
82 data = data + pad * chr(pad)
83 iv = os.urandom(self.blockSize)
84 cipherText = AES.new(encryptionKey, self.mode, iv).encrypt(data)
85 encryptedContent = iv + cipherText
86 encryptedContent = self.__encodeCrypto__(encryptedContent)
87 return encryptedContent, key
88
89 def aesDecrypt(self, key, data):
90 '''Decrypts AES(base64 encoded) Crypto - Returns Decrypted Data'''
91 decryptionKey = self.__extractAESKey__(key)
92 encryptedContent = self.__extractCrypto__(data)
93 iv = encryptedContent[:self.blockSize]
94 cipherText = encryptedContent[self.blockSize:]
95 plainTextwithpad = AES.new(decryptionKey, self.mode, iv).decrypt(cipherText)
96 pad = ord(plainTextwithpad[-1])
97 plainText = plainTextwithpad[:-pad]
98 return plainText
99
100 def generateRSAKeys(self,keyLength):
101 '''Generates Public/Private Key Pair - Returns Public / Private Keys'''
102 private = RSA.generate(keyLength)
103 public = private.publickey()
104 privateKey = private.exportKey()
105 publicKey = public.exportKey()
106 return privateKey, publicKey
107
108 def rsaPublicEncrypt(self, pubKey, data):
109 '''RSA Encryption Function - Returns Encrypted Data'''
110 publicKey = RSA.importKey(pubKey)
111 encryptedData = publicKey.encrypt(data,'')
112 return encryptedData
113
114 def rsaPrivateDecrypt(self, privKey, data):
115 '''RSA Decryption Function - Returns Decrypted Data'''
116 privateKey = RSA.importKey(privKey)
117 decryptedData = privateKey.decrypt(data)
118 return decryptedData
119
120 def rsaSign(self, privKey, data):
121 '''RSA Signing - Returns an RSA Signature'''
122 privateKey = RSA.importKey(privKey)
123 if privateKey.can_sign() == True:
124 digest = SHA256.new(data).digest()
125 signature = privateKey.sign(digest,'')
126 return signature
127 else:
128 raise Exception("Error: Can't Sign with Key")
129
130 def rsaVerify(self, pubKey, data, signature):
131 '''Verifies RSA Signature based on Data received - Returns a Boolean Value'''
132 publicKey = RSA.importKey(pubKey)
133 digest = SHA256.new(data).digest()
134 return publicKey.verify(digest, signature)
135
136 def eccGenerate(self):
137 '''Generates Elliptic Curve Public/Private Keys'''
138 ecc = ECC.generate()
139 publicKey = ecc._public
140 privateKey = ecc._private
141 curve = ecc._curve
142 return privateKey, publicKey, curve
143
144 def eccEncrypt(self,publicKey, curve, data):
145 '''Encrypts Data with ECC using public key'''
146 ecc = ECC(1, public=publicKey, private='', curve=curve)
147 encrypted = ecc.encrypt(data)
148 return encrypted
149
150 def eccDecrypt(self,privateKey, curve, data):
151 '''Decrypts Data with ECC private key'''
152 ecc = ECC(1, public='', private=privateKey, curve=curve)
153 decrypted = ecc.decrypt(data)
154 return decrypted
155
156 def eccSign(self, privateKey, curve, data):
157 '''ECC Signing - Returns an ECC Signature'''
158 ecc = ECC(1, public='', private=privateKey, curve=curve)
159 signature = ecc.sign(data)
160 return signature
161
162 def eccVerify(self, publicKey, curve, data, signature):
163 '''Verifies ECC Signature based on Data received - Returns a Boolean Value'''
164 ecc = ECC(1, public=publicKey, private='', curve=curve)
165 return ecc.verify(data, signature)
166
167 if __name__ == '__main__':
168 '''Usage Examples'''
169
170 print '''
171
172 Python Crypto Wrapper - By Chase Schultz
173
174 Currently Supports: AES-256, RSA Public Key, RSA Signing, ECC Public Key, ECC Signing
175
176 Dependencies: pyCrypto - https://github.com/dlitz/pycrypto
177 PyECC - https://github.com/rtyler/PyECC
178
179 '''
180
181 '''Instantiation of Crypto Wrapper and Message'''
182 crypto = CryptoWrapper();
183 message = 'Crypto Where art Thou... For ye art a brother...'
184 print 'Message to be Encrypted: %s\n' % message
185
186
187 '''AES ENCRYPTION USAGE'''
188 '''***Currently Supporting AES-256***'''
189 encryptedAESContent, key = crypto.aesEncrypt(message)
190 print 'Encrypted AES Message: %s\nEncrypted with Key: %s' % (encryptedAESContent, key)
191 decryptedAESMessage = crypto.aesDecrypt(key, encryptedAESContent)
192 print '\nDecrypted AES Content: %s\n' % decryptedAESMessage
193
194
195 '''RSA ENCRYPTION USAGE'''
196 privateKey, publicKey = crypto.generateRSAKeys(2048)
197
198 encryptedRSAContent = crypto.rsaPublicEncrypt(publicKey, message)
199 print 'Encrypted RSA Message with RSA Public Key: %s\n' % encryptedRSAContent
200 decryptedRSAMessage = crypto.rsaPrivateDecrypt(privateKey, encryptedRSAContent)
201 print '\nDecrypted RSA Content with RSA Private Key: %s\n' % decryptedRSAMessage
202
203
204 '''RSA SIGNING USAGE'''
205 signature = crypto.rsaSign(privateKey, message)
206 print 'Signature for message is: %s\n ' % signature
207 if crypto.rsaVerify(publicKey, message, signature) is False:
208 print 'Could not Verify Message\n'
209 else:
210 print 'Verified RSA Content\n'
211
212 '''ECC ENCRYPTION USAGE'''
213 eccPrivateKey, eccPublicKey, eccCurve = crypto.eccGenerate()
214
215 encryptedECCContent = crypto.eccEncrypt(eccPublicKey, eccCurve , message)
216 print 'Encrypted ECC Message with ECC Public Key: %s\n' % encryptedECCContent
217 decryptedECCContent = crypto.eccDecrypt(eccPrivateKey, eccCurve, encryptedECCContent)
218 print 'Decrypted ECC Content with ECC Private: %s\n' % decryptedECCContent
219
220 '''ECC SIGNING USAGE'''
221 signature = crypto.eccSign(eccPrivateKey, eccCurve, message)
222 print 'Signature for message is: %s\n ' % signature
223 if crypto.eccVerify(eccPublicKey, eccCurve, message, signature) is False:
224 print 'Could not Verify Message\n'
225 else:
226 print 'Verified ECC Content\n'
227
228
229
来源:oschina
链接:https://my.oschina.net/u/4413726/blog/3971772