java加解密算法

编程入门 行业动态 更新时间:2024-10-19 23:24:09

java加解密算法

最近在搞报文加解密的一些业务,一路总是坑坑洼洼的。

首先,部分内容是从别的地方搬运过来的。https://www.oschina/question/2534721_2143246?sort=default

 

知识点1:

sonarLint对加密算法使用的一些规范:


Encryption algorithms should be used with secure mode and padding scheme
 
Vulnerability
 
Blocker
java:S5542
 
To perform secure cryptography, operation modes and padding scheme are essentials and should be used correctly according to the encryption algorithm:
For block cipher encryption algorithms (like AES), the GCM (Galois Counter Mode) mode that works internally with zero/no padding scheme, is recommended. At the opposite, these modes and/or schemes are highly discouraged:
Electronic Codebook (ECB) mode is vulnerable because it doesn't provide serious message confidentiality: under a given key any given plaintext block always gets encrypted to the same ciphertext block.
Cipher Block Chaining (CBC) with PKCS#5 padding (or PKCS#7) is vulnerable to padding oracle attacks.
RSA encryption algorithm should be used with the recommended padding scheme (OAEP)
Noncompliant Code Example
  Cipher c0 = Cipher.getInstance("AES"); // Noncompliant: by default ECB mode is chosen  
 Cipher c1 = Cipher.getInstance("AES/ECB/NoPadding"); // Noncompliant: ECB doesn't provide serious message confidentiality  
 Cipher c3 = Cipher.getInstance("Blowfish/ECB/PKCS5Padding"); // Noncompliant: ECB doesn't provide serious message confidentiality  
 Cipher c4 = Cipher.getInstance("DES/ECB/PKCS5Padding"); // Noncompliant: ECB doesn't provide serious message confidentiality    
 Cipher c6 = Cipher.getInstance("AES/CBC/PKCS5Padding"); // Noncompliant: CBC with PKCS5 is vulnerable to oracle padding attacks  
 Cipher c7 = Cipher.getInstance("Blowfish/CBC/PKCS5Padding"); // Noncompliant: CBC with PKCS5 is vulnerable to oracle padding attacks  
 Cipher c8 = Cipher.getInstance("DES/CBC/PKCS5Padding"); // Noncompliant: CBC with PKCS5 is vulnerable to oracle padding attacks  
 Cipher c9 = Cipher.getInstance("AES/CBC/PKCS7Padding"); // Noncompliant: CBC with PKCS7 is vulnerable to oracle padding attacks  
 Cipher c10 = Cipher.getInstance("Blowfish/CBC/PKCS7Padding"); // Noncompliant: CBC with PKCS7 is vulnerable to oracle padding attacks  
 Cipher c11 = Cipher.getInstance("DES/CBC/PKCS7Padding"); // Noncompliant: CBC with PKCS7 is vulnerable to oracle padding attacks    
 Cipher c14 = Cipher.getInstance("RSA/NONE/NoPadding"); // Noncompliant: RSA without OAEP padding scheme is not recommanded  


Compliant Solution
  // Recommended for block ciphers  
 Cipher c5 = Cipher.getInstance("AES/GCM/NoPadding"); // Compliant    
 // Recommended for RSA  
 Cipher c15 = Cipher.getInstance("RSA/None/OAEPWithSHA-1AndMGF1Padding"); // Compliant  
 Cipher c16 = Cipher.getInstance("RSA/None/OAEPWITHSHA-256ANDMGF1PADDING"); // Compliant  
 
See
OWASP Top 10 2017 Category A6 - Security Misconfiguration
MITRE, CWE-327 - Use of a Broken or Risky Cryptographic Algorithm
CERT, MSC61-J. - Do not use insecure or weak cryptographic algorithms
SANS Top 25 - Porous Defenses

知识点2:

3DES加密还有细分,你这里用的是DESede/CBC/NoPadding,

DESede表示加密方式是3DES,

CBC表示加密模式,这个模式不好解释常用的还有ECB

NoPadding表示填充模式,java中常用的还有PKCS5Padding

解释完了,怎么解决呢?

你要问对方3DES使用了什么加密模式,什么填充方式,然后你选择对应的解密模式和填充算法

常用的有:DESede/ECB/PKCS5Padding,DESede/ECB/NoPadding,DESede/CBC/PKCS5Padding,DESede/CBC/NoPadding,

加密模式没有太大的问题,主要是填充方式,如果对方不是PKCS5Padding或者不是兼容的方式那么,你必须要选择NoPadding,然后手动将他填充的去掉,就是你上面说的无法正常显示的字符

再说一下3DES加密过程:

3DESkey有24个字节,通过java内置算法会得到三个key用来给原数据三次加密,所以为什么是叫3DES

然后原数据按每8个字节分组,所以这里就产生了填充的问题,如果你的原数据不是8的整数倍字节,就需要填充满8的倍数,填充的字节就是填充模式决定的,PKCS5Padding的填充模式比较邪,他的算法是如果还缺5个字节,那么用0x05填充5个,如果还缺4个字节那么用0x04填充4个,以此类推,如果缺1个那么用0x01填充1个,注意,如果你的数据正好是8的倍数,那么他还会神奇的再填充8个0x08。

 

知识点3:

首先,加解密是有iv向量的,所以是cbc模式,至于padding的方式,可以先用NoPadding ,这样解密得到的结果是不会错的,只不过会多一些加密时的补位,根据解密结果byte[] 补位的数据 判断补位方式是PKCS7Padding。

通过分析Nopadding模式得到的byte[] 发现密文是有错误的,重新要了密文,解决了问题

至于java 里支持PKCS7Padding 需要引用 bcprov-jdk16-144.jar 来添加支持。

在代码添加        Security.addProvider(new com.sun.crypto.provider.SunJCE());
             Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());

代码。 然后Cipher cipher = Cipher.getInstance(Algorithm); 可以写成Cipher cipher = Cipher.getInstance(Algorithm,"BC"); 。

 

知识点4:

对于3des加密算法,加密key的长度问题,长度要求24个字符,真实业务中也有可能少于24或大于24。不同情况的处理方式:

=24:

private static SecretKeySpec getSecretKey1(final String key) {
    return new SecretKeySpec(key.getBytes(), KEY_ALGORITHM);
}

>24:

private static SecretKeySpec getSecretKey(final String key) {
        //返回生成指定算法密钥生成器的KeyGenerator 对象
        KeyGenerator kg = null;
        try {
            kg = KeyGenerator.getInstance(KEY_ALGORITHM);
            kg.init(168, new SecureRandom(key.getBytes()));
            //生成一个密钥
            SecretKey secretKey = kg.generateKey();
            return new SecretKeySpec(secretKey.getEncoded(), KEY_ALGORITHM);
            // 转换为DESede专用密钥
        } catch (NoSuchAlgorithmException ex) {
            ex.printStackTrace();
        }
        return null;
    }

<24:

忘了,找不到了。

 

终极知识点5:

更多推荐

java加解密算法

本文发布于:2023-06-14 09:55:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1463060.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:算法   加解密   java

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!