ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

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

2019-06-28 12:49:56  阅读:236  来源: 互联网

标签:java openssl encryption javax-crypto


我必须使用bash脚本加密字符串,就像我使用javax.crypto.Cipher加密一样.在java我使用AES-256键,键“0123456789”.但是当我使用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"));
    }
}

d230b216e9d65964abd4092f5c455a21

解决方法:

如果无数的在线十六进制转换器不起作用,那么您只需将您在Java中使用的密钥打印为十六进制即可.关于这个壮举,Here是一个流行的SO问题.

完成后,您将看到它仍然无效,因为您使用的是不同的算法.

使用Cipher.getInstance(“AES”)时;它很可能默认为“AES / ECB / PKCS5Padding”,它与“aes-256-cbc”不同,因为ECB和CBC是两个完全不同的modes of operation.为了防止这种歧义总是完全符合你的密码,例如:密码.getInstance( “AES / CBC / PKCS5Padding”);.

然后,您在Java中生成的密钥只有16个字节长,因此OpenSSL中的匹配密码将是“aes-128-ecb”.

正如dave_thompson_085在comment中所说:

> echo添加了Java代码未添加的换行符.您需要以这种方式创建明文:echo -n“lun01”.如果您使用的是Windows,请参阅this.
>您的Java代码将结果输出为十六进制,因此您需要在OpenSSL中执行相同操作.您需要删除OpenSSL命令中的-a选项以防止Base64编码,然后您可以利用其他命令行工具(如od on linux)将二进制输出数据转换为带有od -tx1的十六进制.
>完整命令:

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

不要使用ECB模式!它在语义上不安全.您需要至少使用带有随机IV的CBC模式(检查它是随机的,而不仅仅是零字节).

更好的方法是添加身份验证,例如添加带有加密 – 然后 – MAC方法的HMAC标记,或者只使用像GCM这样的身份验证模式.

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

标签:java,openssl,encryption,javax-crypto
来源: https://codeday.me/bug/20190628/1315592.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有