17 AES对密钥key长度的优化

  1. 接上文,AES的密钥长度再底层定义了固定的长度,16,24,32.但是再实际生产情况下,可能会出现比较任意长度的密钥,如何处理?
  2. 在获取加解密对象的时候特殊处理:
import com.yutu.pwd.util.HexUtils;
import org.junit.jupiter.api.Test;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
/**
 * Aes加密
 */
public class AESTest {
    private static final String UTF8 = StandardCharsets.UTF_8.name();

    //加密算法名称
    private static final String ALGORITHM = "AES";
    //AES默认的长度只有16,24,32
    private static final String KEY = "12345678abcdefghss";

    @Test
    public void S() throws Exception{
        String str = "小汪学java";
        //DES加密
        String encrypt = encrypt(str);
        System.out.println("16进制 + Aes 加密后的字符串: " + encrypt);
        System.out.println("------------------------");
        String decrypt = decrypt(encrypt);
        System.out.println("16进制 + Aes 解密后的字符串: " + decrypt);
    }

    /**
     * des加密
     * @param text 待加密的内容
     * @return
     */
    private String encrypt(String text) throws Exception{
        Cipher cipher = getCipher2(Cipher.ENCRYPT_MODE, KEY);
        //加密
        byte[] encodedBytes = cipher.doFinal(text.getBytes(UTF8));
        return HexUtils.covertBytes2HexStr(encodedBytes);
    }

    /**
     * 解密
     * @param encodedStr 加密后的字符串
     * @return
     * @throws Exception
     */
    private String decrypt(String encodedStr) throws Exception{
        byte[] bytes = HexUtils.convertHex2Bytes(encodedStr);
        //Cipher cipher = Cipher.getInstance(ALGORITHM);
        Cipher cipher = getCipher2(Cipher.ENCRYPT_MODE, KEY);
        SecretKey secretKey = new SecretKeySpec(KEY.getBytes(UTF8), ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE,secretKey);//解密模式
        //获取解码后的字节数组
        byte[] decryptBytes = cipher.doFinal(bytes);
        return new String(decryptBytes,UTF8);
    }

    /**
     * 获取Cipher对象
     * @param type  加解密模式
     * @param seed  密钥key
     * @return
     */
    private Cipher getCipher(int type,String seed) throws Exception{
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        SecretKey secretKey = new SecretKeySpec(seed.getBytes(UTF8), ALGORITHM);
        cipher.init(type,secretKey);//解密模式
        return cipher;
    }

    /**
     * 不管传递的是多少位长度的密钥,最后都会生成指定长度的密钥
     * @param type
     * @param seed
     * @return
     * @throws Exception
     */
    private Cipher getCipher2(int type,String seed) throws Exception{
        Cipher cipher = Cipher.getInstance(ALGORITHM);

        //获取KeyGenerator对象,可以根据传入的key生成一个指定长度的key
        KeyGenerator keyGenerator = KeyGenerator.getInstance(ALGORITHM);

        SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");//此处是生成key的规则算法
        secureRandom.setSeed(seed.getBytes(UTF8));

        keyGenerator.init(128,secureRandom);

        //通过keyGenerator生成新的密钥
        SecretKey secretKey = keyGenerator.generateKey();
        //获取新密钥的字节数组
        byte[] encoded = secretKey.getEncoded();

        SecretKey secretKeySpec = new SecretKeySpec(encoded, ALGORITHM);
        cipher.init(type,secretKeySpec);//解密模式
        return cipher;
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
一般情况下,使用RSA来加密对称密钥AES的方式是: 1. 生成RSA公钥和私钥; 2. 使用RSA公钥来加密AES密钥k,得到密文c; 3. 将密文c和使用AES加密的数据一起发送给接收方; 4. 接收方使用RSA私钥来解密密文c,得到AES密钥k; 5. 使用AES密钥k来解密数据。 具体操作流程如下: 1. 生成RSA公钥和私钥 在使用RSA加密前,需要先生成RSA公钥和私钥。一般情况下,可以使用openssl命令来生成RSA公钥和私钥,具体命令如下: ``` openssl genrsa -out private_key.pem 2048 openssl rsa -in private_key.pem -pubout -out public_key.pem ``` 其中,2048表示生成的RSA密钥长度,private_key.pem表示私钥文件名,public_key.pem表示公钥文件名。 2. 使用RSA公钥来加密AES密钥k 在使用RSA加密AES密钥k前,需要将AES密钥k转换成RSA可加密的格式。一般情况下,可以使用PKCS#1 v1.5标准来进行转换,具体操作如下: ``` openssl rsautl -encrypt -inkey public_key.pem -pubin -in aes_key.txt -out aes_key.enc ``` 其中,public_key.pem表示RSA公钥文件名,aes_key.txt表示AES密钥k所在的文件名,aes_key.enc表示加密后的AES密钥k所在的文件名。 3. 将密文和使用AES加密的数据一起发送给接收方 在将密文和使用AES加密的数据一起发送给接收方前,需要先将密文和使用AES加密的数据进行组合。一般情况下,可以使用tar命令来进行组合,具体命令如下: ``` tar -cvf data.tar aes_data.enc aes_key.enc ``` 其中,aes_data.enc表示使用AES加密后的数据所在的文件名,aes_key.enc表示使用RSA加密后的AES密钥k所在的文件名,data.tar表示组合后的文件名。 4. 接收方使用RSA私钥来解密密文c,得到AES密钥k 在接收方接收到数据后,需要先将密文和使用AES加密的数据进行拆分。一般情况下,可以使用tar命令来进行拆分,具体命令如下: ``` tar -xvf data.tar ``` 其中,data.tar表示组合后的文件名。 接着,使用RSA私钥来解密密文c,得到AES密钥k。具体操作如下: ``` openssl rsautl -decrypt -inkey private_key.pem -in aes_key.enc -out aes_key.txt ``` 其中,private_key.pem表示RSA私钥文件名,aes_key.enc表示加密后的AES密钥k所在的文件名,aes_key.txt表示解密后的AES密钥k所在的文件名。 5. 使用AES密钥k来解密数据 在得到AES密钥k后,就可以使用该密钥来解密数据了。具体操作流程与普通的使用AES解密数据一样,这里不再赘述。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值