Enterprise J2ME Developing Mobile Java Applications [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Enterprise J2ME Developing Mobile Java Applications [Electronic resources] - نسخه متنی

Michael Juntao Yuan

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید



20.3 Password-Based Encryption


One problem with symmetric algorithms is that the users must keep the random keys. Since there is no way users can remember them in their heads, they store the keys in files, and that significantly increases the security risk. Password-based encryption (PBE) schemes use easy-to-remember passwords to generate keys for underlying symmetric parsers. PBE schemes are widely used to protect on-device data. In fact, we can use PBE-protected storages to keep other symmetric or private keys. Now, let's have a look at how PBE works in those libraries. Since the key is generated every time on-the-fly from the password, there is no key serialization process. All operations are contained in the encryption and decryption methods in the CryptoEngine class. For all algorithms, the underlying key generated from the password must be mixed in over and over again with a random "salt" to guarantee security. The iteration number is a programmable parameter and should be at least 1000. Our demo MIDlet for password-based encryption and decryption is shown in Figure 20.2.


Figure 20.2. Password-based encryption using BC's library


Note

The password is stored in a char array instead of in a byte array or a string object. Each character in the password string is 16 bits. A string object is statically allocated by the JVM and could cause security leaks if someone does a memory dump before it is garbage collected.


20.3.1 Bouncy Castle


Password-based encryption and decryption using the Bouncy Castle package are demonstrated in Listing 20.15.

Listing 20.15. Methods for PBE in the Bouncy Castle CryptoEngine example



// Generate random salt
private byte [] salt;
SecureRandom sr = new SecureRandom();
salt = new byte [16];
sr.nextBytes(salt);
// Get password to generate symmetric key with
// (or without IV) To be used in
// an AES underlying cipher
private CipherParameters getAESPasswdKey
(char [] passwd) throws Exception {
PBEParametersGenerator generator =
new PKCS12ParametersGenerator(new SHA1Digest());
generator.init(
PBEParametersGenerator.PKCS12PasswordToBytes(passwd),
salt, 1024);
// Generate a 128 bit key w/ 128 bit IV
ParametersWithIV key =
(ParametersWithIV)generator.generateDerivedParameters(128, 128);
// Generate a 128 kit key
// CipherParameters key =
// generator.generateDerivedParameters(128);
return key;
}
// Password based encryption using AES
public byte [] AESPasswdEncrypt (byte [] toEncrypt,
char [] passwd)throws Exception {
ParametersWithIV key =
(ParametersWithIV) getAESPasswdKey(passwd);
// The following code uses an AES cipher to
// encrypt the message
BufferedBlockCipher cipher = new PaddedBufferedBlockCipher(
new CBCBlockCipher(new AESFastEngine()));
cipher.init(true, key);
byte[] result = new byte[cipher.getOutputSize(toEncrypt.length)];
int len = cipher.processBytes(toEncrypt, 0,
toEncrypt.length, result, 0);
try {
cipher.doFinal(result, len);
} catch (CryptoException ce) {
// handle error
}
return result;
}
// Password based decryption using AES
public byte [] AESPasswdDecrypt (byte [] toDecrypt,
char [] passwd) throws Exception {
ParametersWithIV key = (ParametersWithIV) getAESPasswdKey(passwd);
// The following code uses an AES cipher to
// decrypt the message
BufferedBlockCipher cipher =
new PaddedBufferedBlockCipher(
new CBCBlockCipher(new AESFastEngine()));
cipher.init(false, key);
byte[] result =
new byte[cipher.getOutputSize(toDecrypt.length)];
int len = cipher.processBytes(toDecrypt, 0,
toDecrypt.length, result, 0);
try {
cipher.doFinal(result, len);
} catch (CryptoException ce) {
// handle error
}
return result;
}

In the demo code package (see "Resources"), I have also included an example of PBE using underlying triple DES symmetric key. The triple DES key does not have an IV parameter.


20.3.2 IAIK JCE-ME


The use of PBE in IAIK JCE-ME is similar to that in Bouncy Castle but with a simpler API. I demonstrate the use of RC2 as the underlying cipher in the IAIK example (Listing 20.16).

Listing 20.16. PBE in the IAIK JCE-ME



private byte [] salt;
SecureRandom sr = new SecureRandom();
salt = new byte [16];
sr.nextBytes(salt);
// ... ...
public byte [] PBEEncrypt (byte [] toEncrypt,
char [] passwd) throws Exception {
PBE pbe = PBE.getInstance(PBE.OID_PKCS12_RC2_40_SHA);
Cipher c = pbe.getCipher(Cipher.ENCRYPT_MODE,
passwd, salt, 1024, null);
return c.doFinal(toEncrypt);
}
public byte [] PBEDecrypt (byte [] toDecrypt,
char [] passwd) throws Exception {
PBE pbe = PBE.getInstance(PBE.OID_PKCS12_RC2_40_SHA);
Cipher c = pbe.getCipher(Cipher.DECRYPT_MODE,
passwd, salt, 1024, null);
return c.doFinal(toDecrypt);
}


20.3.3 Phaos Micro Foundation


In the Phaos MF example (Listing 20.17), we use the PKCS #5 scheme to generate the symmetric key. The salt mix-in iteration number is the default 1024 specified by the implementation. In the Phaos MF API, we need to generate the random IV AESinitV for the AES key ourselves. Also, please note that although handling PooledArray is tedious, it produces performance gains on small devices.

Listing 20.17. Password based encryption and decryption using Phaos MF



private byte [] salt;
RandomBitsSource.setDefault(new SecureRBS());;
RandomBitsSource.getDefault().seed();
salt = new byte[PBES2AlgID.DEFAULT_SALT_LENGTH];
RandomBitsSource.getDefault().randomBytes(salt);
// ... ...
// PKCS #5 password scheme 2 using
// AES as underlying cipher
public byte [] AESPasswdEncrypt(byte [] toEncrypt,
String password) throws Exception {
// Use SHA1 with AES
AlgorithmIdentifier algID = new PBES2AlgID(salt,
PBES2AlgID.DEFAULT_ITERATION_COUNT,
PBES2AlgID.KEY_LENGTH_NOT_PRESENT,
AlgIDList.HMAC_WITH_SHA1,
new CBCAlgID(OIDList.AES_128_CBC, AESinitV));
ByteArrayInputStream in = new ByteArrayInputStream(toEncrypt);
PooledArray plaintext = ByteArrayPool.getArray(in.available());
in.read(plaintext.buffer, 0, plaintext.length);
in.close();
// PKCS #5 only uses lower 8 bits of
// each password char
PasswordBasedEncryptionScheme pbes =
PasswordBasedEncryptionScheme.getInstance(algID,
password.getBytes());
PooledArray ciphertext =
pbes.encryptFinal(plaintext.buffer, 0,
plaintext.length);
ByteArrayOutputStream out = new ByteArrayOutputStream ();
algID.output(out);
out.write(ciphertext.buffer, 0,
ciphertext.length);
byte [] encrypted = out.toByteArray();
out.close();
plaintext.release();
ciphertext.release();
return encrypted;
}
// PKCS #5 password scheme 2 decryption
//
// Since the algID is embedded inside the
// encrypted byte array, this method can decrypt
// any Phaos PBES messages with any
// underlying ciphers.
public byte [] AESPasswdDecrypt(byte [] toDecrypt,
String password) throws Exception {
ByteArrayInputStream in = new ByteArrayInputStream(toDecrypt);
AlgorithmIdentifier algID = new AlgorithmIdentifier(in);
PooledArray ciphertext = ByteArrayPool.getArray(in.available());
in.read(ciphertext.buffer, 0, ciphertext.length);
in.close();
PasswordBasedEncryptionScheme pbes =
PasswordBasedEncryptionScheme.getInstance(algID,
password.getBytes());
PooledArray plaintext =
pbes.decryptFinal(ciphertext.buffer, 0,
ciphertext.length);
ByteArrayOutputStream out = new ByteArrayOutputStream ();
out.write(plaintext.buffer, 0, plaintext.length);
byte [] decrypted = out.toByteArray();
out.close();
plaintext.release();
ciphertext.release();
return decrypted;
}


/ 204