Decrypting in Java with Blowfish

后端 未结 6 1933
独厮守ぢ
独厮守ぢ 2021-02-06 18:41

Hullo,

I am encrypting and decrypting in Java with Blowfish.

The encryption works fine, but the decryption fails.

Here is my Java code for decrypting :

相关标签:
6条回答
  • 2021-02-06 19:17

    Converting bytes to hex and back is tricky. This should solve your problem. (You need to fix your string representation of encryptedString)

    Output:

    StackOverflow 537461636B4F766572666C6F77 [83, 116, 97, 99, 107, 79, 118, 101, 114, 102, 108, 111, 119]
    J~3¹ÙÂÖ"¢ª„¨u 194A7E33B9060CD9C2D622A2AA84A875 [25, 74, 126, 51, -71, 6, 12, -39, -62, -42, 34, -94, -86, -124, -88, 117]
    StackOverflow 537461636B4F766572666C6F77 [83, 116, 97, 99, 107, 79, 118, 101, 114, 102, 108, 111, 119]
    

    Code:

    import java.util.Arrays;
    import javax.crypto.Cipher;
    import javax.crypto.KeyGenerator;
    import javax.crypto.SecretKey;
    import javax.crypto.spec.SecretKeySpec;
    
    public class Main {
    
      public static void main(String[] args) throws Exception {
    
        KeyGenerator keygenerator = KeyGenerator.getInstance("Blowfish");
        SecretKey secretkey = keygenerator.generateKey();
    
        String plaintextString = "StackOverflow";
        System.out.println(plaintextString + " " + bytesToHex(plaintextString.getBytes()) + " " + Arrays.toString(plaintextString.getBytes()));
    
        SecretKeySpec key = new SecretKeySpec(secretkey.getEncoded(), "Blowfish");
        Cipher cipher = Cipher.getInstance("Blowfish");
    
        cipher.init(Cipher.ENCRYPT_MODE, key);
        byte[] encrypted = cipher.doFinal(plaintextString.getBytes());
        String encryptedString = bytesToHex(encrypted);
        System.out.println(new String(encrypted) + " " + encryptedString + " " + Arrays.toString(encrypted));
    
        cipher.init(Cipher.DECRYPT_MODE, key);
        byte[] decrypted = cipher.doFinal(hexToBytes(encryptedString));
        String decryptedString = bytesToHex(decrypted);
        System.out.println(new String(decrypted) + " " + decryptedString + " " + Arrays.toString(decrypted));
    
      }
    
      public static byte[] hexToBytes(String str) {
        if (str == null) {
          return null;
        } else if (str.length() < 2) {
          return null;
        } else {
          int len = str.length() / 2;
          byte[] buffer = new byte[len];
          for (int i = 0; i < len; i++) {
            buffer[i] = (byte) Integer.parseInt(str.substring(i * 2, i * 2 + 2), 16);
          }
          return buffer;
        }
    
      }
    
      public static String bytesToHex(byte[] data) {
        if (data == null) {
          return null;
        } else {
          int len = data.length;
          String str = "";
          for (int i = 0; i < len; i++) {
            if ((data[i] & 0xFF) < 16)
              str = str + "0" + java.lang.Integer.toHexString(data[i] & 0xFF);
            else
              str = str + java.lang.Integer.toHexString(data[i] & 0xFF);
          }
          return str.toUpperCase();
        }
      }
    }
    
    0 讨论(0)
  • 2021-02-06 19:18
    String encryptedString = … ;  
    String decryptedString = null;
    SecretKeySpec key = new SecretKeySpec(myKey.getBytes(), "Blowfish");
    private static byte[] linebreak = {}; // Remove Base64 encoder default linebreak
    private static Base64 coder;
    Cipher cipher;
    try {
        coder = new Base64(32, linebreak, true);
        cipher = Cipher.getInstance("Blowfish");
        cipher.init(Cipher.DECRYPT_MODE, key);
        byte[] decrypted = cipher.doFinal(encryptedString.getBytes());
        decryptedString = new String(coder.encode(decrypted));
    } [ catch Exceptions … ]
    

    You can use Base64 class to solve this problem.

    0 讨论(0)
  • 2021-02-06 19:18

    Try this

    private byte[] encrypt(String key, String plainText) throws GeneralSecurityException {
    
        SecretKey secret_key = new SecretKeySpec(key.getBytes(), ALGORITM);
    
        Cipher cipher = Cipher.getInstance(ALGORITM);
        cipher.init(Cipher.ENCRYPT_MODE, secret_key);
    
        return cipher.doFinal(plainText.getBytes());
    }
    

    here you can find whole class with enc/dec --- http://dexxtr.com/post/57145943236/blowfish-encrypt-and-decrypt-in-java-android

    0 讨论(0)
  • 2021-02-06 19:32

    Now I have the solution !

    First, there were some problems with Unicode, so I have put ISO-8859-1 everywhere. Including in the Base64 encoding and decoding.

    Then, I have juggled with the variants.

    Here is my Java code which works for Blowfish decryption :

    String encryptedString = … ;
    String decryptedString = null;
    SecretKeySpec key = new SecretKeySpec(myKey.getBytes(CHARSET_ISO_8859_1), "Blowfish");
    Cipher cipher;
    try {
        cipher = Cipher.getInstance("Blowfish/ECB/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, key);
        byte[] decrypted = cipher.doFinal(encryptedString.getBytes(CHARSET_ISO_8859_1));
        decryptedString = new String(decrypted, CHARSET_ISO_8859_1);
    } [ catch Exceptions … ]
    

    Note that I have replaced "Blowfish" with "Blowfish/ECB/PKCS5Padding" for getting the Cipher instance, but, if you do the same for the key, it fails.

    The key myKey has to be a Latin-1 string of 8 characters. This makes a key of 128 bits. The Blowfish algorithm allows bigger keys, but they fail in Java because of the USA export restriction in the JRE — the USA allow encryption but not stronger than what the NSA can break.

    The CHARSET_ISO_8859_1 is a constant defined like this :

    final Charset CHARSET_ISO_8859_1 = Charset.forName("ISO-8859-1");
    

    And Charset is java.nio.charset.Charset.

    Last but not least, I have changed my encryption Java code accordingly.

    0 讨论(0)
  • 2021-02-06 19:34

    Your myKey variable lenght must be multiple of 8

    0 讨论(0)
  • 2021-02-06 19:37

    You should definitely be more explicit with the Cipher by declaring the mode and padding. How is this code getting encrypted? What is actually in the String encryptedString? Is it hex encoded or base64 encoded? If it isn't encoded that could definitely be a source of trouble.

    0 讨论(0)
提交回复
热议问题