|
|||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
| SUMMARY: INNER | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | ||||||||
java.lang.Object
|
+--org.logi.crypto.Crypto
|
+--org.logi.crypto.keys.K
|
+--org.logi.crypto.keys.RSAKey
An instance of this class handles a single RSA key.
The RSA algorithm is probably the best known and most widely used public key algorithm. Breaking one RSA key is believed to be as difficult as factoring the modulus (n) of the group in which calculations are done. When speaking of the size of an RSA key, it is understood to be the size of this modulus.
The first 512 bit number is expected to be factored by the end of 1999. 1024 bits should be more than enough in most cases, but the clinically paranoid may want to use up to 4096 bit keys.
Each RSA key is a pair (d,n) of integers and matches another key (e,n). If P is a block of plain data represented as an integer smaller than n, then it can be encrypted with the transformation:
E = (P^e) mod n
which has the inverse transformation:
P = (E^d) mod n
The keys' owner will keep (d,n) secret and publish (e,n) as widely as possible. This allows anyone who gets hold of the public key to encrypt data which can only be decrypted with the corresponding private key. All public keys generated with this package will use the exponent 65537.
Data that is encrypted with a private key can similarly only be decrypted with the corresponding public key. This is useful for digital signatures.
When P is created from an array of bytes, it will correspond to as many bytes of plain data as the bytes needed to store n, less one. When encrypting less than a full block of data, the data should be put in the most significant bytes of the plaintext-block and appended with random data. This is done by all relevant classes in the logi.crypto library. The plaintext block is encrypted to form a ciphertext block with as many bytes as are needed to store the modulus.
Note that since signing is the same operation as decryption, you should not sign data from an unknown source with a key also used for decrypting information without hashing it first. I.e. when implementing a system always perform the hashing in a process trusted by the owner of the key, or in speciali circumstances where you wish to sign unknown data, create a separate RSA key-pair for this. This implementation was originally done from a description given in Gallian's Contemporary Abstract Algebra, but various changes from various sources have been incorporated.
When a key-pair is created, the private key will actually be an instance of the RSAKeyChin class, which uses the Chinese Remainder Theorem to speed up exponentiation.
The CDS for the RSAKey class is RSAKey(r,n,pub) for a
public key, RSAKey(r,n,pri) for a private key or
RSAKey(r,n,p) for a private key where we know one factor of
n. In all cases r, n and
p are hexadecimal numbers.
Crypto.fromString(String)| Fields inherited from class org.logi.crypto.Crypto |
BIT, cdsPath, EMPTY_ARRAY, FOUR, keySource, NIBBLE, ONE, primeCertainty, random, TWO, ZERO |
| Constructor Summary | |
RSAKey(java.math.BigInteger r,
java.math.BigInteger n,
boolean pri)
Create a new RSA key (r,n). |
|
| Method Summary | |
BlindFingerprint |
blind(Fingerprint fp,
BlindingFactor bf)
Blind a fingerprint with a public key and the given blinding factor in preparation for blindly signing the fingerprint with the private key. |
int |
cipherBlockSize()
Returns the size of the blocks that can be decrypted in one call to decrypt(). |
BlindingFactor |
createBlindingFactor()
Create a new blinding factor suitable for blinding a fingerprint before being signed with the private key in the pair. |
static KeyPair |
createKeys(java.math.BigInteger r,
java.math.BigInteger s,
java.math.BigInteger n)
Create a KeyPair object holding objects for the public RSA key (r,n) and the private RSA key (s,n). |
static KeyPair |
createKeys(int bitLength)
Create a pair of public/private keys. |
static KeyPair |
createKeys(java.lang.String username,
java.lang.String password,
java.lang.String hashFunction,
int bitLength)
Create a pair of public/private keys from a username/password pair. |
void |
decrypt(byte[] source,
int i,
byte[] dest,
int j)
Decrypt one block of data. |
void |
encrypt(byte[] source,
int i,
byte[] dest,
int j)
Encrypt one block of data. |
boolean |
equals(java.lang.Object o)
Return true iff the two keys are equivalent. |
static java.math.BigInteger |
findPrime(java.math.BigInteger start)
Returns the largest prime p <= start |
java.lang.String |
getAlgorithm()
The name of the algorithm is "RSA". |
java.math.BigInteger |
getExponent()
Return the RSA exponent. |
java.math.BigInteger |
getModulus()
Return the RSA modulus. |
int |
getSize()
Return the size of the key modulo in bits. |
boolean |
isPrivate()
Return true iff this is a private key. |
boolean |
matches(Key key)
Check if a key mathces this. |
static RSAKey |
parseCDS(java.lang.String[] param)
Used by Crypto.fromString when parsing a CDS. |
int |
plainBlockSize()
Returns the size of the blocks that can be encrypted in one call to encrypt(). |
void |
prettyPrint(java.io.PrintWriter out,
int ind,
int rec)
Print this object to out, indented with ind tabs, going down at most rec levels of recursion. |
BlindSignature |
sign(BlindFingerprint fp)
Create a signature for a blinded fingerprint with a private key. |
Signature |
sign(Fingerprint fp)
Create a signature for a Fingerprint with a private key. |
int |
signatureSize()
Returns the length of the signature in bytes. |
int |
signBlockSize()
Returns the maximum size in bytes of the fingerprint that can be signed. |
java.lang.String |
toString()
Return a CDS for this key. |
Signature |
unBlind(BlindSignature bs,
BlindingFactor bf)
Unblind a blind signature using the same blinding factor that was used to blind the original fingerprint. |
boolean |
verify(Signature s,
Fingerprint fp)
Verify a Signature on a Fingerprint with a public key. |
| Methods inherited from class org.logi.crypto.keys.K |
getFingerprint, getFingerprint, hashCode, matchFingerprint, matchFingerprint |
| Methods inherited from class org.logi.crypto.Crypto |
binString, binString, ensureArrayLength, ensureArrayLength, equal, equalRelaxed, equalSub, fromHexNibble, fromHexString, fromString, fromString, hexString, hexString, hexString, hexString, hexString, initRandom, initRandom, makeClass, makeInt, makeLong, makeSessionKey, pastSpace, pickBits, pickBits, prettyPrint, readBlock, readInt, trimArrayLength, trimArrayLength, trimLeadingZeroes, writeBytes, writeBytes, writeInt |
| Methods inherited from class java.lang.Object |
getClass, notify, notifyAll, wait, wait, wait |
| Methods inherited from interface org.logi.crypto.keys.Key |
getFingerprint, getFingerprint, hashCode, matchFingerprint, matchFingerprint |
| Methods inherited from interface org.logi.crypto.PrettyPrintable |
prettyPrint |
| Constructor Detail |
public RSAKey(java.math.BigInteger r,
java.math.BigInteger n,
boolean pri)
(r,n).
It is a private key if pri is true.| Method Detail |
public static RSAKey parseCDS(java.lang.String[] param)
throws InvalidCDSException
A valid CDS can be created by calling the toString() method.
InvalidCDSException - if the CDS is malformed.Crypto.fromString(String)public static java.math.BigInteger findPrime(java.math.BigInteger start)
p <= startpublic static KeyPair createKeys(int bitLength)
bitLength or bitLength-1 bits.
public static KeyPair createKeys(java.lang.String username,
java.lang.String password,
java.lang.String hashFunction,
int bitLength)
throws InvalidCDSException
bitLength or bitLength-1 bits.
The keys are created by hashing the password, appending with
0's until it is bitLength bits long and
searching for a prime pby counting down from there.
Another prime q is found in the same way, but the
username is prepended to the password before hashing. Key-generation
proceeds as normally from there.
The hashFunction parameters directs which hash function to use. It must be the name of a supported hash function, such as MD5 or SHA1.
The username does not need to be secret and can in
fact be a fixed string. It plays a similar role as SALT in unix
password systems in protecting against dictionary attacks.
InvalidCDSException - if the specified hash function is not available.
public static KeyPair createKeys(java.math.BigInteger r,
java.math.BigInteger s,
java.math.BigInteger n)
throws KeyException
(r,n) and the private RSA key (s,n).KeyException - if (r,n) and (s,n) does not describe a valid
pair of RSA keys.public int getSize()
getSize in interface Keypublic java.lang.String getAlgorithm()
getAlgorithm in interface Keypublic java.math.BigInteger getExponent()
public java.math.BigInteger getModulus()
public boolean isPrivate()
isPrivate in interface Keypublic java.lang.String toString()
toString in class java.lang.ObjectCrypto.fromString(java.io.Reader)
public void prettyPrint(java.io.PrintWriter out,
int ind,
int rec)
throws java.io.IOException
prettyPrint in interface PrettyPrintableprettyPrint in class Cryptopublic boolean equals(java.lang.Object o)
equals in class java.lang.Objectpublic final boolean matches(Key key)
matches in interface Keypublic int plainBlockSize()
plainBlockSize in interface CipherKeypublic int cipherBlockSize()
cipherBlockSize in interface CipherKey
public void encrypt(byte[] source,
int i,
byte[] dest,
int j)
source starting at offset i and
ciphertext is written to dest, starting at
offset j.
The amount of data read and written will match the values returned
by plainBlockSize() and cipherBlockSize().
encrypt in interface CipherKey
public void decrypt(byte[] source,
int i,
byte[] dest,
int j)
source starting at offset i and
plaintext is written to dest, starting at
offset j.
The amount of data read and written will match the values returned
by cipherBlockSize() and plainBlockSize().
decrypt in interface CipherKeypublic int signBlockSize()
signBlockSize in interface SignatureKeypublic int signatureSize()
signatureSize in interface SignatureKey
public Signature sign(Fingerprint fp)
throws KeyException
sign in interface SignatureKeyKeyException - if the key modulus is shorter than the signature.KeyException - if this is not a private key
public boolean verify(Signature s,
Fingerprint fp)
throws KeyException
The method returns true iff s is a signature for
fp created with the mathcing private key.
verify in interface SignatureKeyKeyException - if this is not a public keypublic BlindingFactor createBlindingFactor()
createBlindingFactor in interface BlindSignatureKey
public BlindFingerprint blind(Fingerprint fp,
BlindingFactor bf)
throws KeyException
blind in interface BlindSignatureKeyKeyException - if you try to blind with a private keyKeyException - if the BlindingFactor is not an RSABlindingFactor
public BlindSignature sign(BlindFingerprint fp)
throws KeyException
sign in interface BlindSignatureKeyKeyException - if there are problems, depending on the implementing class.
public Signature unBlind(BlindSignature bs,
BlindingFactor bf)
throws KeyException
unBlind in interface BlindSignatureKeyKeyException - if there are problems, depending on the implementing class.
|
|||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
| SUMMARY: INNER | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | ||||||||