|
|||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | ||||||||
java.lang.Object
|
+--java.security.KeyStoreSpi
|
+--org.metastatic.crypto.JKS
This is an implementation of Sun's proprietary key store algorithm, called "JKS" for "Java Key Store". This implementation was created entirely through reverse-engineering.
The format of JKS files is, from the start of the file:
0xFEEDFEED.Then, if the entry is a private key entry:
Otherwise, the entry is a trusted certificate, which is encoded as the name of the encoding algorithm (e.g. X.509), encoded the same way as alias names. Then, a four-byte integer representing the size of the encoded certificate, then that many bytes representing the encoded certificate (e.g. the DER bytes in the case of X.509).
(See this file for some idea of how I was able to figure out these algorithms)
Decrypting the key works as follows:
ekey, is the middle bytes of the
ciphertext.K[0].K[1] ... K[n], where
|K[i]| = 20, n = ceil(|ekey| / 20), and
K[i] = SHA-1(UTF-16BE(password) + K[i-1]).key = ekey ^ (K[1] + ... + K[n]).H =
SHA-1(UTF-16BE(password) + key). If this value does not match
the last 20 bytes of the ciphertext, output FAIL. Otherwise,
output key.The signature is defined as SHA-1(UTF-16BE(password) +
US_ASCII("Mighty Aphrodite") + encoded_keystore) (yup, Sun
engineers are just that clever).
(Above, SHA-1 denotes the secure hash algorithm, UTF-16BE the big-endian byte representation of a UTF-16 string, and US_ASCII the ASCII byte representation of the string.)
The source code of this class should be available in the file JKS.java.
| Constructor Summary | |
JKS()
|
|
| Method Summary | |
java.util.Enumeration |
engineAliases()
|
boolean |
engineContainsAlias(java.lang.String alias)
|
void |
engineDeleteEntry(java.lang.String alias)
|
java.security.cert.Certificate |
engineGetCertificate(java.lang.String alias)
|
java.lang.String |
engineGetCertificateAlias(java.security.cert.Certificate cert)
|
java.security.cert.Certificate[] |
engineGetCertificateChain(java.lang.String alias)
|
java.util.Date |
engineGetCreationDate(java.lang.String alias)
|
java.security.Key |
engineGetKey(java.lang.String alias,
char[] password)
|
boolean |
engineIsCertificateEntry(java.lang.String alias)
|
boolean |
engineIsKeyEntry(java.lang.String alias)
|
void |
engineLoad(java.io.InputStream in,
char[] passwd)
|
void |
engineSetCertificateEntry(java.lang.String alias,
java.security.cert.Certificate cert)
|
void |
engineSetKeyEntry(java.lang.String alias,
byte[] encodedKey,
java.security.cert.Certificate[] certChain)
|
void |
engineSetKeyEntry(java.lang.String alias,
java.security.Key key,
char[] passwd,
java.security.cert.Certificate[] certChain)
|
int |
engineSize()
|
void |
engineStore(java.io.OutputStream out,
char[] passwd)
|
| Methods inherited from class java.lang.Object |
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
| Constructor Detail |
public JKS()
| Method Detail |
public java.security.Key engineGetKey(java.lang.String alias,
char[] password)
throws java.security.NoSuchAlgorithmException,
java.security.UnrecoverableKeyException
engineGetKey in class java.security.KeyStoreSpijava.security.NoSuchAlgorithmException
java.security.UnrecoverableKeyExceptionpublic java.security.cert.Certificate[] engineGetCertificateChain(java.lang.String alias)
engineGetCertificateChain in class java.security.KeyStoreSpipublic java.security.cert.Certificate engineGetCertificate(java.lang.String alias)
engineGetCertificate in class java.security.KeyStoreSpipublic java.util.Date engineGetCreationDate(java.lang.String alias)
engineGetCreationDate in class java.security.KeyStoreSpi
public void engineSetKeyEntry(java.lang.String alias,
java.security.Key key,
char[] passwd,
java.security.cert.Certificate[] certChain)
throws java.security.KeyStoreException
engineSetKeyEntry in class java.security.KeyStoreSpijava.security.KeyStoreException
public void engineSetKeyEntry(java.lang.String alias,
byte[] encodedKey,
java.security.cert.Certificate[] certChain)
throws java.security.KeyStoreException
engineSetKeyEntry in class java.security.KeyStoreSpijava.security.KeyStoreException
public void engineSetCertificateEntry(java.lang.String alias,
java.security.cert.Certificate cert)
throws java.security.KeyStoreException
engineSetCertificateEntry in class java.security.KeyStoreSpijava.security.KeyStoreException
public void engineDeleteEntry(java.lang.String alias)
throws java.security.KeyStoreException
engineDeleteEntry in class java.security.KeyStoreSpijava.security.KeyStoreExceptionpublic java.util.Enumeration engineAliases()
engineAliases in class java.security.KeyStoreSpipublic boolean engineContainsAlias(java.lang.String alias)
engineContainsAlias in class java.security.KeyStoreSpipublic int engineSize()
engineSize in class java.security.KeyStoreSpipublic boolean engineIsKeyEntry(java.lang.String alias)
engineIsKeyEntry in class java.security.KeyStoreSpipublic boolean engineIsCertificateEntry(java.lang.String alias)
engineIsCertificateEntry in class java.security.KeyStoreSpipublic java.lang.String engineGetCertificateAlias(java.security.cert.Certificate cert)
engineGetCertificateAlias in class java.security.KeyStoreSpi
public void engineStore(java.io.OutputStream out,
char[] passwd)
throws java.io.IOException,
java.security.NoSuchAlgorithmException,
java.security.cert.CertificateException
engineStore in class java.security.KeyStoreSpijava.io.IOException
java.security.NoSuchAlgorithmException
java.security.cert.CertificateException
public void engineLoad(java.io.InputStream in,
char[] passwd)
throws java.io.IOException,
java.security.NoSuchAlgorithmException,
java.security.cert.CertificateException
engineLoad in class java.security.KeyStoreSpijava.io.IOException
java.security.NoSuchAlgorithmException
java.security.cert.CertificateException
|
|||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | ||||||||