Encrypting and Decrypting Using Java: Unable to get same output

后端 未结 3 1687
忘了有多久
忘了有多久 2020-12-07 23:58

I am trying to learn and test the java 1.6 encryption/decryption API. I want to know what I am doing wrong and what I am missing in terms of knowledge.

In the code

相关标签:
3条回答
  • 2020-12-08 00:17

    Here's the description from JDK doc:

    DESKeySpec
    public DESKeySpec(byte[] key)
               throws InvalidKeyException
    Creates a DESKeySpec object using the first 8 bytes in key as the key material for the DES key. 
    The bytes that constitute the DES key are those between key[0] and key[7] inclusive. 
    

    DESKeySpec uses only the first 8 bytes of byte[] as key. Thus the actual keys in used are identical in your example.

    0 讨论(0)
  • 2020-12-08 00:23

    Welcome to encryption! As mentioned DES is symmetric and requires the same key for encryption as decryption. That key needs to be the right number of bits for the cipher that you're using. For DES that's 56-bit. Before you go too far with that though, here are a few things you might want to consider:

    1. You should use a stronger encryption standard like AES. It's possible to break DES encryption now.
    2. If you want to use a string as the key, then you should use a strong hash function like SHA-256 against that key string. Then take as many bits from that hash output as you need for the encryption key, 128-bit is plenty sufficient for AES. Your key string should be long like you have.
    3. It'll be best to use a block cipher mode that doesn't generate the same output for the same input each time. See block cipher modes of operation for info and a visualization of why ECB mode is bad.

    Here's a working example of using 128-bit AES encryption in CBC mode with PKCS #5 padding:

    import java.security.MessageDigest;
    import java.security.SecureRandom;
    
    import javax.crypto.Cipher;
    import javax.crypto.spec.IvParameterSpec;
    import javax.crypto.spec.SecretKeySpec;
    
    public class EncryptDecrypt {
        public static void main(String[] args) throws Exception {
            // here are your inputs
            String keyString = "averylongtext!@$@#$#@$#*&(*&}{23432432432dsfsdf";
            String input = "john doe";
    
            // setup AES cipher in CBC mode with PKCS #5 padding
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    
            // setup an IV (initialization vector) that should be
            // randomly generated for each input that's encrypted
            byte[] iv = new byte[cipher.getBlockSize()];
            new SecureRandom().nextBytes(iv);
            IvParameterSpec ivSpec = new IvParameterSpec(iv);
    
            // hash keyString with SHA-256 and crop the output to 128-bit for key
            MessageDigest digest = MessageDigest.getInstance("SHA-256");
            digest.update(keyString.getBytes());
            byte[] key = new byte[16];
            System.arraycopy(digest.digest(), 0, key, 0, key.length);
            SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
    
            // encrypt
            cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
            byte[] encrypted = cipher.doFinal(input.getBytes("UTF-8"));
            System.out.println("encrypted: " + new String(encrypted));
    
            // include the IV with the encrypted bytes for transport, you'll
            // need the same IV when decrypting (it's safe to send unencrypted)
    
            // decrypt
            cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
            byte[] decrypted = cipher.doFinal(encrypted);
            System.out.println("decrypted: " + new String(decrypted, "UTF-8"));
        }
    }
    
    0 讨论(0)
  • 2020-12-08 00:31

    Here's a working example of using 56-bit DES encryption.

    import javax.crypto.Cipher;
    import javax.crypto.SecretKey;
    import javax.crypto.spec.SecretKeySpec;
    
    public class CipherHelper {
    
        // Algorithm used
        private final static String ALGORITHM = "DES";
    
        /**
         * Encrypt data
         * @param secretKey -   a secret key used for encryption
         * @param data      -   data to encrypt
         * @return  Encrypted data
         * @throws Exception
         */
        public static String cipher(String secretKey, String data) throws Exception {
            // Key has to be of length 8
            if (secretKey == null || secretKey.length() != 8)
                throw new Exception("Invalid key length - 8 bytes key needed!");
    
            SecretKey key = new SecretKeySpec(secretKey.getBytes(), ALGORITHM);
            Cipher cipher = Cipher.getInstance(ALGORITHM);
            cipher.init(Cipher.ENCRYPT_MODE, key);
    
            return toHex(cipher.doFinal(data.getBytes()));
        }
    
        /**
         * Decrypt data
         * @param secretKey -   a secret key used for decryption
         * @param data      -   data to decrypt
         * @return  Decrypted data
         * @throws Exception
         */
        public static String decipher(String secretKey, String data) throws Exception {
            // Key has to be of length 8
            if (secretKey == null || secretKey.length() != 8)
                throw new Exception("Invalid key length - 8 bytes key needed!");
    
            SecretKey key = new SecretKeySpec(secretKey.getBytes(), ALGORITHM);
            Cipher cipher = Cipher.getInstance(ALGORITHM);
            cipher.init(Cipher.DECRYPT_MODE, key);
    
            return new String(cipher.doFinal(toByte(data)));
        }
    
        // Helper methods
    
        private static byte[] toByte(String hexString) {
            int len = hexString.length()/2;
    
            byte[] result = new byte[len];
    
            for (int i = 0; i < len; i++)
                result[i] = Integer.valueOf(hexString.substring(2*i, 2*i+2), 16).byteValue();
            return result;
        }
    
        public static String toHex(byte[] stringBytes) {
            StringBuffer result = new StringBuffer(2*stringBytes.length);
    
            for (int i = 0; i < stringBytes.length; i++) {
                result.append(HEX.charAt((stringBytes[i]>>4)&0x0f)).append(HEX.charAt(stringBytes[i]&0x0f));
            }
    
            return result.toString();
        }
    
        private final static String HEX = "0123456789ABCDEF";
    
        // Helper methods - end
    
        /**
         * Quick test
         * @param args
         */
        public static void main(String[] args) {
            try {
    
                String secretKey    = "01234567";
                String data="test";
                String encryptedData = cipher(secretKey, data);
    
                System.out.println("encryptedData: " + encryptedData);
    
                String decryptedData = decipher(secretKey, encryptedData);
    
                System.out.println("decryptedData: " + decryptedData);
    
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
    }
    
    0 讨论(0)
提交回复
热议问题