Skip to content
This repository was archived by the owner on Oct 14, 2021. It is now read-only.

Commit a8a47a7

Browse files
author
amk
committed
[project @ amk-19981214021948-ae4d136d34b577c7]
[project @ 1998-12-13 18:19:48 by amk] Initial revision
0 parents  commit a8a47a7

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

115 files changed

+30504
-0
lines changed

.bzrignore

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
project.log
2+
tailor.state
3+
tailor.state.old
4+
tailor.state.journal

ChangeLog

+112
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
2+
Changes since 1.1a1
3+
===================
4+
* Most importantly, the distribution has been broken into two
5+
parts: exportable, and export-controlled. The exportable part
6+
contains all the hashing algorithms, signature-only public key
7+
algorithms, chaffing & winnowing, random number generation, various
8+
utility modules, and the documentation.
9+
10+
The export-controlled part contains public-key encryption
11+
algorithms such as RSA and ElGamal, and bulk encryption algorithms
12+
like DES, IDEA, or Skipjack. Getting this code still requires that
13+
you go through an access control CGI script, and denies you access if
14+
you're outside the US or Canada.
15+
16+
* Added the RIPEMD hashing algorithm. (Contributed by
17+
Hirendra Hindocha.)
18+
19+
* Implemented the recently declassified Skipjack block
20+
encryption algorithm. My implementation runs at 864 K/sec on a
21+
PII/266, which isn't particularly fast, but you're probably better off
22+
using another algorithm anyway. :)
23+
24+
* A simple XOR cipher has been added, mostly for use by the
25+
chaffing/winnowing code. (Contributed by Barry Warsaw.)
26+
27+
* Added Protocol.Chaffing and Hash.HMAC.py. (Contributed by
28+
Barry Warsaw.)
29+
30+
Protocol.Chaffing implements chaffing and winnowing, recently
31+
proposed by R. Rivest, which hides a message (the wheat) by adding
32+
many noise messages to it (the chaff). The chaff can be discarded by
33+
the receiver through a message authentication code. The neat thing
34+
about this is that it allows secret communication without actually
35+
having an encryption algorithm, and therefore this falls within the
36+
exportable subset.
37+
38+
* Tidied up randpool.py, and removed its use of a block
39+
cipher; this makes it work with only the export-controlled subset
40+
available.
41+
42+
* Various renamings and reorganizations, mostly internal.
43+
44+
Changes since 1.0.2
45+
===================
46+
47+
* Changed files to work with Python 1.5; everything has been
48+
re-arranged into a hierarchical package. (Not backward compatible.)
49+
The package organization is:
50+
Crypto.
51+
Hash.
52+
MD2, MD4, MD5, SHA, HAVAL
53+
Cipher.
54+
ARC2, ARC4, Blowfish, CAST, DES, DES3, Diamond,
55+
IDEA, RC5, Sapphire
56+
PublicKey.
57+
DSA, ElGamal, qNEW, RSA
58+
Util.
59+
number, randpool, RFC1751
60+
61+
Since this is backward-incompatible anyway, I also changed
62+
module names from all lower-case to mixed-case: diamond -> Diamond,
63+
rc5 -> RC5, etc. That had been an annoying inconsistency for a while.
64+
65+
* Added CAST5 module contributed by <[email protected]>.
66+
67+
* Added qNEW digital signature algorithm (from the digisign.py
68+
I advertised a while back). (If anyone would like to suggest new
69+
algorithms that should be implemented, please do; I think I've got
70+
everything that's really useful at the moment, but...)
71+
72+
* Support for keyword arguments has been added. This allowed
73+
removing the obnoxious key handling for Diamond and RC5, where the
74+
first few bytes of the key indicated the number of rounds to use, and
75+
various other parameters. Now you need only do something like:
76+
77+
from Crypto.Cipher import RC5
78+
obj = RC5.new(key, RC5.ECB, rounds=8)
79+
80+
(Not backward compatible.)
81+
82+
* Various function names have been changed, and parameter
83+
names altered. None of these were part of the public interface, so it
84+
shouldn't really matter much.
85+
86+
* Various bugs fixed, the test suite has been expanded, and
87+
the build process simplified.
88+
89+
* Updated the documentation accordingly.
90+
91+
Changes since 1.0.1:
92+
====================
93+
94+
* Changed files to work with Python 1.4 .
95+
96+
* The DES and DES3 modules now automatically correct the
97+
parity of their keys.
98+
99+
* Added R. Rivest's DES test (see http://theory.lcs.mit.edu/~rivest/destest.txt)
100+
101+
Changes since 1.0.0:
102+
103+
* REDOC III succumbed to differential cryptanalysis, and has
104+
been removed.
105+
106+
* The crypt and rotor modules have been dropped; they're still
107+
available in the standard Python distribution.
108+
109+
* The Ultra-Fast crypt() module has been placed in a separate
110+
distribution; see <http://starship.skyport.net/crew/amk/maintained/crypto.html>.
111+
112+
* Various bugs fixed.

Cipher/__init__.py

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
2+
__all__ = ['ARC2', 'Blowfish', 'DES', 'DES3', 'IDEA', 'RC5', 'Diamond', 'CAST',
3+
'Skipjack', 'ARC4', 'Sapphire', 'XOR' ]
4+
5+
6+

Demo/README

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
This directory contains demonstration files that use the modules
2+
included in the Python Cryptography Toolkit.
3+
4+
Note: These programs have version numbers of their own, which are not
5+
necessarily the same as the version number of the Toolkit package.
6+
7+
cipher Encrypt and decrypt sensitive files; type 'cipher -h'
8+
for a usage message.
9+
10+
voice Allows secure voice communication over a TCP/IP link.
11+
Currently this is Linux-specific; changes to make it
12+
run on other systems would be greatly appreciated.
13+
14+
RSAgen.py Generates a new RSA key. Demonstrates using
15+
randpool.py, and maintains a file of random data in
16+
"randseed". Requires that the IDEA and MD5 modules
17+
are installed.
18+
19+
testkey.py RSA public/private key pair used by example programs.
20+
21+
Secure importing of Python modules:
22+
23+
sign.py Sign all *.pyc files in a directory, using the
24+
key defined in testkey.py.
25+
26+
secimp.py Implementation of the secure 'import' command.
27+
28+
29+

Demo/cipher

+150
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
#!/usr/bin/env python
2+
# -*-Python-*-
3+
# Cipher 1.00
4+
#
5+
# Part of the Python Cryptography Toolkit, version 1.1
6+
#
7+
# This program is distributed in the hope that it will be useful,
8+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
9+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10+
#
11+
12+
import sys, getopt, os
13+
14+
# Determine the name of this executable
15+
executable = os.path.basename(sys.argv[0])
16+
if executable=='': executable='cipher'
17+
cipher = '' # Unknown ciphering algorithm
18+
key = (0, '') # Empty key
19+
magic = 'ctx\001' # Magic string prefixed to the data
20+
NoInputFile = '' # Exceptions raised on file errors
21+
NoOutputFile = ''
22+
23+
def PrintUsage():
24+
print 'Usage: cipher [OPTIONS] file1 file2 ...'
25+
print '\n -c ciphername Force use of ciphername to encrypt/decrypt'
26+
print ' -k key Key to use for encryption/decryption'
27+
print '\nThe default cipher algorithm is IDEA; if no key is set on the command'
28+
print 'line, you will be prompted to enter a key.'
29+
print 'Files are read completely into memory, so do not try to encrypt'
30+
print 'very large files.'
31+
32+
def GenerateIV(length):
33+
import whrandom
34+
IV=''
35+
for i in range(0, length):
36+
IV=IV + chr(int(256*whrandom.random()))
37+
return IV
38+
39+
def Encipher(filename, cipher, key):
40+
if (cipher==''): cipher='IDEA'
41+
try:
42+
exec ('from Crypto.Cipher import '+cipher)
43+
module=eval(cipher)
44+
except ImportError:
45+
print executable+ ':', cipher, ': Cipher does not exist.'
46+
sys.exit(1)
47+
import Crypto.Hash.MD5
48+
try:
49+
input=open(filename, 'r')
50+
except IOError:
51+
raise NoInputFile
52+
try:
53+
output=open(filename+'.cip', 'w')
54+
except IOError:
55+
raise NoOutputFile, filename+'.cip'
56+
57+
if (key[0]==0):
58+
key=raw_input('Enter encryption key for '+ filename+ ':')
59+
else: key=key[1]
60+
key=Crypto.Hash.MD5.new(key).digest()
61+
IV=''
62+
for i in range(0, module.blocksize): IV=IV+'A'
63+
if (module.keysize==0):
64+
cipherobj=module.new(key, module.CBC, IV)
65+
else:
66+
cipherobj=module.new(key[0:module.keysize], module.CBC, IV)
67+
output.write(magic+cipher+'\0')
68+
data = GenerateIV(module.blocksize)
69+
filedata=input.read()
70+
data = data + magic + str(len(filedata))+'\0'+filename+'\0'
71+
data = data + filedata
72+
input.close()
73+
padding=module.blocksize - (len(data) % module.blocksize)
74+
for i in range(0, padding):
75+
data = data + chr(i)
76+
ciphertext=cipherobj.encrypt(data)
77+
output.write(ciphertext)
78+
output.close()
79+
80+
def Decipher(filename, cipher, key):
81+
import Crypto.Hash.MD5, string
82+
try:
83+
input=open(filename, 'r')
84+
except IOError:
85+
raise NoInputFile
86+
if (input.read(len(magic))!=magic):
87+
print executable+':', filename+': Does not seem to be a ciphered file'
88+
return
89+
t=''
90+
while (1):
91+
c=input.read(1)
92+
if (ord(c)==0): break
93+
t=t+c
94+
if (cipher==''): cipher=t
95+
try:
96+
from Crypto.Cipher import *
97+
module=eval(cipher)
98+
except ImportError:
99+
print executable+ ':', cipher, ': Cipher does not exist.'
100+
sys.exit(1)
101+
if (key[0]==0):
102+
key=raw_input('Enter encryption key for '+ filename+ ':')
103+
else: key=key[1]
104+
key=Crypto.Hash.MD5.new(key).digest()
105+
IV = ''
106+
for i in range(0, module.blocksize): IV=IV+'A'
107+
data=input.read()
108+
if (module.keysize==0):
109+
cipherobj=module.new(key, module.CBC, IV)
110+
else:
111+
cipherobj=module.new(key[0:module.keysize], module.CBC, IV)
112+
plain=cipherobj.decrypt(data) # Decrypt the data
113+
plain=plain[module.blocksize:] # Discard first block of random data
114+
if (plain[0:len(magic)]!=magic):
115+
print executable+':', filename+': Incorrect key or cipher algorithm'
116+
return
117+
else: plain=plain[len(magic):]
118+
i=string.find(plain, '\0')
119+
length=string.atoi(plain[0:i])
120+
j=string.find(plain, '\0', i+1)
121+
newfilename=plain[i+1:j]
122+
try:
123+
output=open(newfilename, 'w')
124+
except IOError:
125+
raise NoOutputFile, newfilename
126+
output.write(plain[j+1:j+1+length])
127+
output.close()
128+
129+
if len(sys.argv)==1: PrintUsage() ; sys.exit(0)
130+
131+
options, args=getopt.getopt(sys.argv[1:], 'c:k:hH')
132+
for opt in options:
133+
letter, param = opt
134+
if (letter=='-c'): cipher = param
135+
if (letter=='-k'): key = (1, param)
136+
if (letter=='-h' or letter=='-H'):
137+
PrintUsage()
138+
sys.exit(0)
139+
140+
for file in args:
141+
try:
142+
if (file[-4:]=='.cip'):
143+
Decipher(file, cipher, key)
144+
else:
145+
Encipher(file, cipher, key)
146+
except NoInputFile:
147+
print executable+ ':', file+ ': No such file.'
148+
except NoOutputFile, filename:
149+
print executable+ ':', filename+ ': Cannot open file'
150+

Demo/secimp/README

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
2+
This is a simple demonstration of adding an import hook that verifies
3+
a digital signature on a Python code object before allowing it to be
4+
imported. There are three files:
5+
6+
* sign.py, which signs all the *.pyc files in the directories
7+
listed on the command line. The contents of the .pyc file is stored
8+
along with the signature in a file whose name ends with .pys .
9+
10+
* secimp.py, which implements a secimport() function which
11+
will use *.pys files.
12+
13+
* testkey.py is the key used to sign and verify *.pys files.
14+
15+
To try it out:
16+
1. Run "sign.py ." to compile and sign all the *.py files in
17+
the current directory.
18+
19+
2. Run secimp.py from the command-line; it will try to
20+
securely import testkey.pys, which should succeed.
21+
22+
3. Fire up your favorite editor, and change a single byte in a
23+
string somewhere in testkey.pys. Run secimp.py again; it should raise
24+
an exception when the signature can't be verified.

0 commit comments

Comments
 (0)