【问题标题】:Blowfish GoLang Encryption and Java DecryptionBlowfish GoLang 加密和 Java 解密
【发布时间】:2018-12-23 16:29:38
【问题描述】:

无法解密在 Java 中使用 Blowfish 在 GoLang 中加密的密文。

加密

import (
    "testing"
    "golang.org/x/crypto/blowfish"
    "github.com/andreburgaud/crypt2go/ecb"
    "github.com/andreburgaud/crypt2go/padding"
    "fmt"
    "encoding/base64"
)

func TestEncrypt(t *testing.T) {

    bytes := []byte("cap")
    key := []byte("1c157d26e2db9a96a556e7614e1fbe36")

    encByte := encrypt(bytes, key)
    enc := base64.StdEncoding.EncodeToString(encByte)
    fmt.Printf("ENC - %s\n", enc)
}

func encrypt(pt, key []byte) []byte {
    block, err := blowfish.NewCipher(key)
    if err != nil {
        panic(err.Error())
    }
    mode := ecb.NewECBEncrypter(block)
    padder := padding.NewPkcs5Padding()
    pt, err = padder.Pad(pt) // padd last block of plaintext if block size less than block cipher size
    if err != nil {
        panic(err.Error())
    }
    ct := make([]byte, len(pt))
    mode.CryptBlocks(ct, pt)
    return ct
}

// Output
// ENC - AP9atM49v8o=

解密

import lombok.SneakyThrows;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;

import static java.util.Base64.getDecoder;
import static java.util.Base64.getEncoder;

public class UserAuthenticationFilter {

    public static void main(String[] args) throws Exception {
        String key = "1c157d26e2db9a96a556e7614e1fbe36";
        System.out.println(decrypt(getDecoder().decode("AP9atM49v8o="), key));

        // encryption and decryption verification
        // String plainText = "cap";
        // String cipher = encrypt(plainText, key);
        // String decrypted = decrypt(getDecoder().decode(enc), key);
        // assert decrypted.equals(plainText);
    }

    @SneakyThrows
    public static String encrypt(String plainText, String key) {
        byte[] myKeyByte = hexToBytes(key);
        SecretKeySpec skeySpec = new SecretKeySpec(myKeyByte, "Blowfish");
        Cipher ecipher = Cipher.getInstance("Blowfish/ECB/PKCS5Padding");
        ecipher.init(Cipher.ENCRYPT_MODE, skeySpec);

        byte[] src = ecipher.doFinal(plainText.getBytes("ISO-8859-1"));
        return getEncoder().encodeToString(src);
    }

    @SneakyThrows
    public static String decrypt(byte[] cipherContent, String key) {
        byte[] myKeyByte = hexToBytes(key);
        SecretKeySpec skeySpec = new SecretKeySpec(myKeyByte, "Blowfish");
        Cipher dcipher = Cipher.getInstance("Blowfish/ECB/NoPadding");
        dcipher.init(2, skeySpec);
        byte[] dcontent = dcipher.doFinal(cipherContent);
        return (new String(dcontent, "ISO-8859-1")).trim();
    }

    private 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;
        }
    }

}

// Output
// BY x³

根据输出,GoLang 中的加密和 Java 中的解密不会产生相同的纯文本。最初,认为问题可能与base64编码和解码中涉及的golang的字节(0到255)和java的字节(-128到127)有关。但是戳Java的解密代码,value &amp; 255处理正确。

在 golang 中解密相同的密文效果很好。 Java中的加密和解密也很完美。但不是一个加密,另一个解密。

我认为加密和解密逻辑是正确的。唯一的猜测可能是有一些特定的语言???密文移植到其他语言解密时丢失。

【问题讨论】:

  • 解密时不指定填充,加密时使用填充。
  • @Michael 为了测试 Java 中的加密和解密,我使用Blowfish/ECB/PKCS5Padding 进行加密,使用Blowfish/ECB/NoPadding 进行解密,这可以按预期工作。所以我认为如果填充是问题,它已经与BadPaddingException
  • 请将信息编辑到问题中
  • 我相信您的问题出在 golang 示例的 bytes 中。我不是 golang 专家,但我假设您正在从字符串字符创建一个字节数组,而不是解码十六进制值
  • @gusto2 明白了..!问题在于将密钥转换为字节 [],而不是解码十六进制,只需将其转换为字节。您可以将此作为答案发布。

标签: java go encryption cryptography blowfish


【解决方案1】:
key := []byte("1c157d26e2db9a96a556e7614e1fbe36")

我相信这段代码返回字符串本身的字节数组,而不是十六进制解码值。要获取有效密钥,您可以尝试使用hex decoding

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-09-25
    • 1970-01-01
    • 1970-01-01
    • 2016-10-14
    • 2014-05-13
    • 1970-01-01
    • 2019-05-15
    • 2015-05-02
    相关资源
    最近更新 更多