Chapter 4 80 java.security.Key Once we have a key, getEncoded()will return an encoded form of the key as a byte array. We can then encrypt that byte array with a PBE cipher, like so: byte[] keyBytes = myKey.getEncoded(); cipher.init(Cipher.ENCRYPT_MODE, passwordKey, paramSpec); byte[] encryptedKeyBytes = cipher.doFinal(keyBytes); Those encrypted key bytes can then be written to more permanent storage, like a file or a database. SecretKeySpec To decrypt a key, we need to use the class SecretKeySpec. SecretKeySpec implements SecretKey, but can be constructed from a byte array. We decrypt the key bytes using the PBE cipher, and then we construct an instance of SecretKeySpec with the decrypted bytes and the name of the algorithm: cipher.init(Cipher.DECRYPT_MODE, passwordKey, paramSpec); byte[] keyBytes = cipher.doFinal(encryptedKeyBytes); SecretKeySpec myKey = new SecretKeySpec(keyBytes, "Blowfish"); We'll show an example of encrypting a key with PBE and storing it for future use later in this chapter (in the example using cipher streams). In order to understand how stream ciphers work, we need to first examine in more detail how ciphers themselves work, specifically their mode and padding. Let's begin by looking at padding. Padding Block ciphers, like most of the ciphers we've been discussing so far, operate on distinct chunks of data – usually 64 bits. Some newer block ciphers like AES operate on 128 bits or more at a time. But the plaintext data to be encrypted won't always be a multiple of the block size. So before encrypting, padding needs to be added to the data. There are a number of different ways padding can be added, but most symmetric algorithms use one of two types of padding: q No padding q PKCS#5 padding No padding is exactly that, no padding. It requires that the data we are encrypting end on a block exactly, with no extra data. PKCS#5 is more commonly used. PKCS stands for Public Key Cryptography Standard, and there are a number of PKCS standards created for use in various cryptographic functions, like key exchange and certificate requests. Along with those broad protocol definitions, they also define some padding methods. Of these methods, PKCS#5 is the most commonly used for symmetric encryption. PKCS#5 padding works as follows: the bytes remaining to fill a block are assigned a number, which is the number of bytes that were added to fill the block. For instance, if we have an 8-byte block, and only 3 bytes are filled, then we have 5 bytes to pad. Those 5 bytes are all assigned the value "5", for the 5 bytes of padding. The illustration opposite should help clarify this: