logi.crypto Status and Plans
This is the read.me file for the java package is.logi.crypto,
version 1.0.4, dated 1999.04.01.
Installation
Requirements
- A java 1.1 compatible virtual machine. Most implementation dependant
behaviour is in the user interface code, which logi.crypto doesn't use
at all, so there is no reason why it shouldn't work on all platforms.
- A good feel for how cryptography works. I'm sorry, but no matter
how easy to use the package becomes, you need a fair understanding
of cryptography to be able to use it securely. The system will, for
example, lose all security if you publish the wrong keys or trust
keys from an unknown party. Badly used cryptography is worse than
none at all. Read a book.
Current State
Working Features
- The RSA algorithm with the RSAKey class.
- The ElGamal algorithm with the ElGamalKey class.
- The DES algorithm with the DESKey class.
- Triple DES with the TriDESKey class. (EDE with three sub-keys).
- Encrypting/decrypting arbitrary byte arrays in ECB, CBC, CFB or OFB
mode with any of the above ciphers using the EncryptXXX and
DecryptXXX classes.
- Encryption/decryption of streams with optional non-interactive
key-exchange with the EncryptStream and DecryptStream classes.
- Encryption/decryption of streams with optional interactive
key-exchange with the CipherStreamClient and CipherStreamServer
classes.
- Key 'exchange' by sending a hash of the key to use when decrypting
with the SendHashKeyExClient and SendHashKeyExServer classes.
- Key exchange by sending encrypted keys (including RSA key-exchange)
with the EncryptedKeyExClient and EncryptedKeyExServer classes.
- Diffie-Hellman key exchange with the DHKeyExClient and DHKeyExServer
classes.
- Diffie-Hellman key pre-distribution with the DHKeyExNoninter and
DHKey classes.
- Key exchange and verification with DHEKEKeyExchangeClient and
DHEKEKeyExchangeServer.
- MD5 Fingerprinting with the MD5State and Fingerprint classes.
- SHA-1 Fingerprinting with the SHA1State and Fingerprint classes.
- Signatures with those keys that support them.
- Key certificates. (as signatures of KeyRecord objects.)
- Strong continually re-seeding random-number generation with the
RandomSpinner class
- Storing and retrieveing keys, fingerprints and key-rings with the
toString() and Crypto.fromString() methods.
Known or Possible Bugs
- In CBC and CFB mode, if the first array passed to decrypt() doesn't
contain at least the entire IV, an index-out-of-bounds error occurs.
I have yet to see this actually happen.
Plans
Plans for future versions
- More encryption/signature algorithms, such as IDEA, DSA, etc.
- More protocols, such as Schnorr, proof of knowledge of discreete
logarithm, proof that two discreete logarithms are equal, etc.
- Better key authentication similar to the PGP web-of-trust.
- Key-server class for automatic key exchange.
- More demonstration programs.
- A class to pre-calculate random numbers and store them in a buffer.
- More key-exchange and authentication protocols.
- Secret sharing.
- Blind signatures.
- Anything else people are interested in.
These won't be added in any particular order. If there is something you
would like to see in logi.crypto, send me mail and I'll move it forward
in the queue.
History
Version 1.0.4 (1999.04.01)
- Switched to jdk1.2, mostly for the greatly improved javadoc. The
package will still be tested with jdk1.1.x.
- Cleaned up a lot of @see javadoc mismatches thanks to the new
javadoc.
- Fixed bug in how EncryptStream and DecryptStream execute
non-interactive protocols. Thanks for Frank Fowler for leading me
in the right direction.
- Added the ElGamalKey class for encryption and signatures.
- Changed the way fingerprints are calculated for Diffie-Hellman keys.
They now use SHA1 and also hash in the group modulus. I can't see
that the old fingerprint should be weak, but just switching to SHA1
makes it even stronger.
- Fixed DHKey.matches(key).
- Enforce that signatures can only be created with private/secret keys
and verified with public keys in symmetric algorithms. This meant
adding a "throws KeyException" to SignatureKey.verify(...). Changed
RSAKey accordingly. This may break existing code!
Version 1.0.3 (1999.02.24)
- Cleaned up the protocol interfaces. The KeyExchangeClient and
KeyExchangeServer interfaces are gone as they added no abstraction
over the KeyExClient and KeyExServer interfaces.
- Added the protocol.InterAuthClient and
protocol.InterAuthServer interfaces to define authentication
interactive protocols. Made the DHEKE classes implement these
interfaces (i.e. added to the implements list).
- Added the QRAuthClient and QRAuthServer classes to implement a
simple query-response protocol for simultaneously authenticating
both the client and the server.
Version 1.0.2 (1999.02.13)
- Added the BlowfishKey class for the blowfish cipher. It is about 15
times faster than triple-DES.
- Renamed the packages from is.logi.crypto.* to is.logi.crypto.*
- Change Cryptonite to Crypto wherever it appeared in a class name.
- Bugfix: Crypto.fromHexNibble and Crypto.fromHexString would not work
correctly for upper-case hexadecimal strings.
- Bugfix: The various equals() methods would throw an exception when
called with a null argument. Thanks to Erwin Bolwidt for pointing this
out.
- test.TestKey now checks the code against test-vectors stored in
vector.name where name is tha name of the algorithm. Test-vectors are
included for DES and Blowfish. Needless to say, the package passes the
tests :-)
Version 1.0.1 (1999.01.08)
- Changed the inner workings of Cryptonite.fromString to use static
methods in the classes it generates rather than constructors. This
is more flexible and allows things like:
- Created protected RSAKeyChin subclass of RSAKey. This class stores the
factorization of the modulus and can do faster modular exponentation.
The speed increase is close to twofold. Instances are created for
private keys whenever possible and should be transparent to the user.
- Added support for Signature objects to Cryptonite.fromString().
- Bugfix: RSAKey.equals() always returned true. (This was not a security
risk, but still important)
Version 1.0.0 (1999.01.01)
- Bugfix: Added random padding in RSA signatures. This was a potential
weakness, especially for hash functions with small output sets.
- Gave access to some settings in the RandomSpinner.
- Changed the RandomSpinner to launch a separate thread to do
initialization. This reduces the load-time especially with a large
initial entropy pool.
Version 0.90 (1998.12.20)
- (Version 0.90 was in some places called 0.95. Oops!)
- Created the is.logi.crypto.sign and
is.logi.crypto.random packages and
moved the appropriate classes to them.
- Cleaned up the MD5 code a bit.
- Renamed hash.FingerprintState to hash.HashState
- Rewrote RandomSpinner so it initially generates an entropy pool
from the Spinner class and then hashes it repeatedly to generate
pseudo-random numbers. Each time it is re-hashed additional entropy
is injected into the pool. This is about 8 times faster than the old
RandomSpinner, but still slower than SecureRandom.
- Created random.PureSpinner which is similar to the old RandomSpinner
class.
- Wrote test.TestRandom to test the various random number generators,
including java.util.Random and java.security.SacureRandom.
Version 0.54 (1998.11.25)
- Created several super-interfaces of the KeyEx interfaces, to
define various generic protocols.
- Added the CipherStreamClient.execute(InterProtocolClient) and
CipherStreamServer.execute(InterProtocolServer) methods to execute
arbitrary interactive cryptographic protocols.
- Added the EncryptStream.execute(NoninterProtocolClient) and
DecryptStream.execute(InterProtocolClient) methods to execute
arbitrary interactive cryptographic protocols.
- Split the is.logi.crypto into sever packages:
- is.logi.crypto
- is.logi.crypto.hash
- is.logi.crypto.io
- is.logi.crypto.keys
- is.logi.crypto.modes
- is.logi.crypto.protocols
- is.logi.crypto.test
I hope it is obvious what goes in the sub-packages. The rest stays
in is.logi.crypto.
- Folded the is.logi.crypto.util package into
is.logi.crypto.test
- The various CDS methods now search through Cryptonite.cdsPath for
classes.
Version 0.53 (1998.11.16)
- Improved the packaging. There is now a jar file in the distribution
and spearate archives for source and documentation.
- I took the time to learn some simple unix shell programming. The
packaging scripts now check that the links and dates in the doc
directory are correct.
- Reviewed all the javadocs.
- Deleted the redundant method
Fingerprint.create(byte[] buf, String algorithm)
- Changed the default random number generator to use /dev/urandom in
stead of /dev/random. This is a SHA1 based generator (like
java.security.SecureRandom) but injects environment noise as it
becomes available.
- Bugfix: TriDES.equals() always returned false.
- Bugfix: Rewrote SignStream and VerifyStream so that flush() now
works.
Version 0.52 (1998.11.06)
- Bugfix: Renamed the CBF classes to CFB. Ooops...
- Moved all test code for key classes to
is.hi.logir.cryponite.test.TestKey
- Moved all test code for mode classes to
is.hi.logir.cryponite.test.TestMode
- Added methods to the CipherStreamClient and CipherStreamServer classes to
return the agreed-upon key. This allows you to agree upon a key and
then use it for multiple connections thereafter.
- Moved all test code for stream and key-exchange classes to
is.hi.logir.cryponite.test.TestCliSer, which also tests multithreaded
use.
- Bugfix: DecryptOFB would thrown a NullPointerException is getKey() was
called before the first decrypt operation.
- Bugfix: CipherStreamClient did not work with non-interactive
key-exchange objects.
- Moved the CDS test to is.hi.logir.cryponite.test.TestCDS
- Moved the SignStram and VerifyStream tests to
is.hi.logir.cryponite.test.TestSign
Version 0.51 (1998.11.03)
- Bugfix: catch SecurityException when applets try to initialize the
default random-number generator to use /dev/random. Thak you
Henrik Kniberg.
- Bugfix: Various ClassName(String) constructors were protected which
makes it invisible to the introspector on some jvm's. Thanks again to
Henrik Kniberg.
- Added the EncryptOFB and DecryptOFB classes for Output Feedback Mode,
with the xor-stream pre-calculated in a separate thread.
- Made the appropriate methods in the EncryptXXX, DecryptXXX and
Stream classes synchronized. (Key classes need no synchronized
methods, for their internal state is immutable!). Thanks to Bartek
Teodorczyk for allerting me to the problem.
Version 0.50 (1998.11.02)
- I now have all the features I want before version 1.0. Thus the jump
in version number. I have written DH-EKE classes, but have not talked
to the patent holders about licensing issues and don't dare distribute
them yet.
- Renamed the Key class to K and added the Key interface which is now
implemented by all key classes and is the ancestor of SignatureKey
and CipherKey. This is probably the 'correct' way to do this in java.
- Added the DHEKEKeyEx, DHEKEKeyExClient and DHEKEKeyExServer classes
for Encrypted Key Exchenge with the Diffie-Hellman algorithms (DH-EKE).
- Fixed a bug in EncryptCBC which caused garbled output if the first block
to be encrypted was not at index 0 in its array.
- Added the EncryptMode.flush(byte[],int,int) method.
- Added the SHA1State object and made it the default hash function
everywhere.
- Rewrote the FingerprintState.create() method, so each sub-class doesn't
need a create method.
- Changed the RSA code to use the public exponent 65537 in stead of 17.
This makes some protocol failures less damaging.
- Added the EncryptCBF and DecryptCBF classes.
- Added the SignStream and VerifyStream classes to sign/verify streams or
to insert/verify fingerprints.
- Rewrote the license without actually changing it.
Version 0.11 (1998.09.29)
- Added the CipherStreamClient and CipherStreamServer classes to apply
interactive key-exchange and subsequent encryption to a pair of
streams.
- Added pre-calculated Difie-Hellman (m,g) pairs for 1024 and 2048 bit
modulo sizes.
- Converted the CipherKey class to an interface and created the
SymmetricKey class which implements some of the abstract methods from
Key. The Key classes are now neater and all the default behaviour in
Key which was not appropriate for asymmetric keys is gone.
- Made all the constructors used by Cryptonite.fromString() protected.
- Renamed some classes. DiffieHellman becomes DH. KeyExchange becomes
KeyEx and Interactive become Inter. The new DHKeyExNoninter class
used to be called DiffieHellmanKeyExchangeNoninteractive which was
getting ridiculous.
- Added the DHKey class.
- Added a constructor to the DHKeyExClient and DHKeyExServer to
initialize with a given DHKey object.
- Added the DHKeyExNoninter class for Diffie-Hellman key
pre-distribution.
Version 0.10 (1998.09.21)
- Added the Diffie-Hellman key-echange classes (but no classes currently
use the interactive key-exchange interfaces, so they can't be used
yet.
- Implemented RSA signatures.
- Renamed the KeyCertificate class to KeyRecord.
- Added methods to allow signing of KeyRecords. This would be a key
certificate, but I'm still thinkng about just how to implement this
properly.
- Added the EncryptedKeyExchange classes, which can be used for RSA
key-exchange.
- Enabled EncryptStream/DecryptStream to work without any key-exchange.
- Optimized the f function in the DESKey class. It is now 2.5 times
faster (on the non-jit blackdown jdk1.1.6-2 jvm for linux).
- Added the TriDESKey class. It is actually much faster than the old DESKey
class.
- Split the SendHashKeyExchange class into SendHashKeyExchangeClient and
SendHashKeyExchangeServer classes, which makes a much cleaner design
and catches more programmer errors (mine too).
- Removed the EncryptMode.empty() and EncryptMode.bytesEncrypted() methods.
Yell at me if you think this is a bad idea, but I just can't see how they
are useful.
- Added the EncryptCBC and DecryptCBC classes.
- Added the RandomFromReader class. Cryptonite will by default try to
use the /dev/random device for random numbers, but falls back to the
RandomSpinner class.
Version 0.09 (1998.09.16)
- Major re-write. I've simplified most of the code and made it more
general. This version is a few months later than I expected, since
I inadvertently aquired a life. This should no longer be a problem.
- The name of the package changed from IS.logi.crypto to
is.logi.crypto, which is contrary to the guidelines set down
by Sun, but doesn't cause as many problems on Windows 95 machines
(and probably Windows 98, although I wouldn't know).
- Renamed the RsaKey class to RSAKey.
- Got rid of the damned kludge of a Data class. Let's hope the generation
scavenging garbage collection that Sun is going to use is as good as
they say. (My programing languages professor liked it...)
- Rewrote most of the fingerprint code. To quickly create an MD5
fignerprint use FingerprintState.createFingerprint(..., "MD5")
- Added the EncryptMode/DecryptMode classs to support various block
cipher modes, such as ECB and CBC.
- Added the EncryptECB and DecryptECB classes.
- Moved all encryption/decryption methods from the Key class to a new
sub-class, CipherKey, and made it the superclass of all keys that are
used for encryption/decryption (and not only key-exchange or
signatures)
- Simplified the CipherKey class (which used to be the Key class) so
that it only encrypts and decrypts single blocks of data. The logic
to manage larger buffers has been moved to the EncryptMode classes.
- Added the SignatureKey interface for keys that can be used to
create and check signatures.
- Relaxed the license a little. You can now use old versions of
Cryptonite indefinately. (But must pay for pre-release versions
once the final version is out, unless you are using the GPL)
- Created the Cryptonite class and made it the superclass of all the
other classes. It includes various utility functions and the default
random number generator.
- Changed all toString() methods so the strings they return completely
define the object.
- Added the Cryptonite.fromString() method to recreate objects from the
strings returned by toString(). Try fromString("DESKey(?)")
to create random DES keys.
- Added the KeySource interace.
- Threw out the overly complicated KeyRing class and added a nice and
simple KeyRing class which implements the KeySource interface.
- Added various key-exchange interfaces with long and complicated
names.
- Added the SendHashKeyExchange class which exchanges keys by sending
the hash of the key and expecting the other side to look up the key
in its default KeySource.
- Totally re-wrote the EncryptStream and DecryptStream objects. They
now use the non-interactive key-exchange classes and the
encrypt/decrypt-mode classes to do all the work. This is much cleaner
and more versatile. (The EncryptStream code is very elegant now,
especially compared to the earlier mess.)
- Probably other things that I've long since forgotten.
Version 0.08 (97.12.21)
- Added the TeaKey class, which implements the TEA cipher. It was
written by a third party who would not be known, but heavily modified
by myself.
- Changed the Streams and Key classes so the stream doesn't have to
keep track of the size of plain-text blocks, but only of the
cipher-text blocks. This made the Key.getEncryptedSize() method
redundant.
- Added the Data class to handle byte buffers. It can resize the buffer
at the users request and return fingerprints.
- Changed DecryptStream so it re-uses buffer arrays when possible and
gives the garbage-collector less to do. This is done by using the Data
class.
- Added the Key.blockSize() and changed EncryptStream so it uses a buffer
size that is a multiple of Key.blockSize(), which is more space
efficient.
- Modified EncryptStream so that it always writes a key-identifier block.
- Added support for session keys to EncryptStream and DecryptStream.
I tested it using a 32-iteration Tea session key with a 512-bit RSA
key to encrypt and decrypt a 200KB text file. Encryption actually
slowed down by 25%, but decryption speed increased by some small 2438%.
- Converted the readme file to HTML.
Version 0.07 (97.11.07)
- Fixed a bug in RsaKey that added garbage after the data when encrypting
- Fixed a bug in DecryptStream that would return negative integers when
reading a byte larger than 127 in read()
- Created a new package, IS.logi.crypto.util, to hold various
utility programs that use Cryptonite.
- Added a simple MD5 hash generation utility to the utility package.
Version 0.06 (97.11.06)
- Moved the creation of FingerprintState objects by name from the
Fingerprint class to the FingerprintState class.
- Got MD5State to work (by stealing time away from my studies)
Version 0.05 (97.10.12)
- Restructured the class hierarchy to allow support for other fingerprint
algorithms by subclassing Fingerprint.
- Added methods to the Key class so that its subclasses can register
themselves whereafter instances can be created by using the algorithm
name.
- Cleaned up the DecryptStream.getBlock() method. I even understand it
now!
- Moved the test programs into their own package called
IS.logi.crypto.test. This uncovered a horrendous bug: All
the constructors in EncryptStream were invisible from outside the
class! No wonder no-one was using the damned thing :-)
Version 0.04 (97.09.07)
- Restructured the class hierarchy to allow support for other encryption
algorithms. This included moving key-generation back into the key
class, renaming Key to RsaKey and creating an abstract Key class.
- Re-created the KeyPair class, but only as a holder for a
public/private key-pair.
- Defined the Fingerprint method for MD5 fingerprints, but used a weak
hash function.
- Implemented the Signature class and the KeyRing.isValid(Key) method.
Version 0.03 (97.08.26)
- Added the EncryptStream, DescryptStream and KeyRing classes.
- Removed the KeyPair class and moved key-generation into the
KeyRing class.
Version 0.02 (97.08.20)
- Got encryption and decryption of large blocks of data working.
- Moved key generation into a new KeyPair class.
Version 0.01 (97.08.17)
- Created the is.hi.logir.cryptonite package.
- Created the Key class (only for RSA).
- Got key generation and encrption/decryption of data blocks
with fewer bits than the key working.
Version 0.00 (97.04.??)
- Passed the Abstract Algebra I test and started thinking about
implementing the RSA algorithm.
Other Notes
- I am considering creating a "weak" version of logi.crypto that can only
create and use small key sizes. This would probably only involve
changing the Key classes and would make the export of software using
logi.crypto legal from countries which disallow the export of strong
cryptography.
This weak version would be built so that it could be replaced by the
user with the strong version. If you are interested in such a version
of logi.crypto, contact me.
If you are interested in a weak version of logi.crypto that can't be
replaced with a stronger version, then I don't want to know.
[ General info
| Status & Plans
| FAQ
| Commercial License
| Class docs
| Online
]
[ Logi Ragnarsson
| Send Mail ]