以与Java相同的方式使用OpenSSL进行加密



我必须使用bash脚本加密字符串,就像我使用javax.crypto.Cipher加密一样。在java中,我使用密钥为"0123456789"的AES-256。但是当我使用openssl时,我不得不将"0123456789"转换为十六进制,但结果与java 不同

echo "lun01" | openssl aes-256-cbc -e -a -K 7573746f726530313233343536373839 -iv 7573746f726530313233343536373839

dpMyN7L5HI8VZEs1biQJ7g==

Java:

public class CryptUtil {
    public static final String DEFAULT_KEY = "0123456789";
    private static CryptUtil instance;
    private String chiperKey;
    private CryptUtil(String chiperKey) {
        this.chiperKey = chiperKey;
    }
    public static CryptUtil getInstance() {
        if (null == instance) {
            instance = new CryptUtil(DEFAULT_KEY);
        }
        return instance;
    }
    public static CryptUtil getInstance(String cipherkey) {
        instance = new CryptUtil(cipherkey);
        return instance;
    }
    public String aesEncrypt(String plainText) {
            byte[] keyBytes = Arrays.copyOf(this.chiperKey.getBytes("ASCII"), 16);
            SecretKey key = new SecretKeySpec(keyBytes, "AES");
            Cipher cipher = Cipher.getInstance("AES");
            cipher.init(Cipher.ENCRYPT_MODE, key);
            byte[] cleartext = plainText.getBytes("UTF-8");
            byte[] ciphertextBytes = cipher.doFinal(cleartext);
            final char[] encodeHex = Hex.encodeHex(ciphertextBytes);
            return new String(encodeHex);
        return null;
    }
    public static void main(String[] args) {
        CryptUtil cryptUtil = CryptUtil.getInstance();
        System.out.println(cryptUtil.aesEncrypt("lun01"));
    }
}

d230b216e9d65964bd4092f5c455a21

如果无数的在线十六进制转换器不适合您,那么您可以简单地将Java中使用的密钥打印为十六进制。这是一个关于壮举的SO常见问题。

完成后,你会发现它仍然不起作用,因为你使用的是不同的算法。

当你使用CCD_ 1时,它很可能默认为"0";AES/EBC/PKCS5Padding";这与";aes-256-cbc";,因为ECB和CBC是两种完全不同的运作模式。为了防止这种歧义,请始终完全限定您的密码,例如:Cipher.getInstance("AES/CBC/PKCS5Padding");

那么您在Java中生成的密钥只有16字节长,因此OpenSSL中的匹配密码将是";aes-128-ecb";。

正如dave_thompson_085在评论中所说:

  • echo添加了一个换行符,Java代码没有添加该换行符。您需要以这种方式创建明文:echo -n "lun01"。如果你在Windows上,也可以看到这个。

  • 您的Java代码将结果输出为十六进制,因此您需要在OpenSSL中执行同样的操作。您需要删除OpenSSL命令中的-a选项以防止Base64编码,然后您可以使用其他命令行工具,如linux上的od,使用od -tx1将二进制输出数据转换为十六进制。

  • 完整命令:

      echo -n lun01 |openssl aes-128-ecb -K 30313233343536373839000000000000 |od -tx1
    

安全建议

不要使用ECB模式!它在语义上不安全。您至少需要将CBC模式与随机IV一起使用(检查它是否是随机的,而不仅仅是零字节(。

更好的方法是添加身份验证,例如使用先加密后MAC的方法添加HMAC标签,或者简单地使用像GCM这样的身份验证模式。

其他信息

如果你使用的是ECB以外的任何东西,那么你就不能在两个版本中加密相同的东西,并期望出现相同的密文。由于它是随机的,您需要在一个版本中加密,在另一个版本进行解密,以确保兼容性。

相关内容

  • 没有找到相关文章

最新更新