0


数据库加密AES 适用 Mysql Oracle 以及java

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录


前言

备忘录:加密key为:vU4C!~0_HQtlU_p@ 可采用任意长度为16位的字符串

数据库数据需要对敏感数据进行加密,比如手机号,身份证号以及银行卡号等进行加密。需要一套通用的加密方法可以在java项目以及oracle和mysql数据库中通用。于是在参考其他博主文件后有如下解决方案。此博客仅作为备忘录使用,并作技术交流。。


一、Mysql

加密:
SELECT to_base64(AES_ENCRYPT(‘4564879512346895654’,‘vU4C!~0_HQtlU_p@’));
解密:
SELECT AES_DECRYPT(from_base64(‘sQtqbsu/05NDCngxv/3al84bdzwtIFG91Zr6hZDpOvE=’),
‘vU4C!~0_HQtlU_p@’);
解密出来时blob文本如果想改成string可以使用如下解密语句
SELECT CONVERT(AES_DECRYPT(from_base64('sQtqbsu/05NDCngxv/3al84bdzwtIFG91Zr6hZDpOvE='),
'vU4C!~0_HQtlU_p@') USING utf8mb4) as field_value;

二、Oracle

1.赋予角色加密权限并创建函数

因为是oracle,所以首先得确定你使用的角色是否拥有加密数据的权限,否则无法使用DBMS_CRYPTO包。

oracle常用的权限查询指令

查看拥有权限的用户有哪些:
select * from dba_tab_privs where table_name = 'DBMS_CRYPTO' and owner = 'SYS';
执行以下sql:grant execute on sys.dbms_crypto to myuser;//myuser 是你oracle当前使用的角色

函数如下(示例):

-- 加密
create or replace FUNCTION FUN_ENCRYPTION(
V_STR VARCHAR2
)
RETURN VARCHAR2
AS
V_KEY_RAW RAW(16);
V_STR_RAW RAW(2000);
V_RETURN_STR VARCHAR2(2000);
V_TYPE PLS_INTEGER ;
BEGIN
    IF V_STR IS NULL OR V_STR ='null' THEN 
     BEGIN 
         RETURN V_STR;
     END;
    ELSE 
     BEGIN 
         V_KEY_RAW := UTL_I18N.STRING_TO_RAW('vU4C!~0_HQtlU_p@','UTF8');
         V_STR_RAW := UTL_I18N.STRING_TO_RAW(V_STR,'UTF8');
         V_TYPE := DBMS_CRYPTO.ENCRYPT_AES128+DBMS_CRYPTO.CHAIN_ECB+DBMS_CRYPTO.PAD_PKCS5 ;
         V_STR_RAW := DBMS_CRYPTO.ENCRYPT(SRC => V_STR_RAW , typ => V_TYPE, key => V_KEY_RAW);
         V_RETURN_STR := utl_raw.cast_to_varchar2(utl_encode.base64_encode(V_STR_RAW));
         RETURN V_RETURN_STR ;
     END;
    END IF ;
END;
-- 解密
create or replace FUNCTION FUN_DECRYPTION(
V_STR VARCHAR2
)
RETURN VARCHAR2
AS
V_KEY_RAW RAW(16);
V_STR_RAW RAW(2000);
V_RETURN_STR VARCHAR2(2000);
V_TYPE PLS_INTEGER ;
BEGIN
    IF V_STR IS NULL OR V_STR ='null' THEN 
     BEGIN 
         RETURN V_STR;
     END;
    ELSE 
     BEGIN 
         V_KEY_RAW := UTL_I18N.STRING_TO_RAW('vU4C!~0_HQtlU_p@','UTF8');
         V_STR_RAW := utl_encode.base64_decode(utl_raw.cast_to_raw((V_STR)));
         V_TYPE := DBMS_CRYPTO.ENCRYPT_AES128+DBMS_CRYPTO.CHAIN_ECB+DBMS_CRYPTO.PAD_PKCS5 ;
         V_STR_RAW := DBMS_CRYPTO.DECRYPT(SRC => V_STR_RAW , typ => V_TYPE, key => V_KEY_RAW );
         V_RETURN_STR := UTL_I18N.RAW_TO_CHAR(V_STR_RAW,'UTF8');
         RETURN V_RETURN_STR ;
     END;
    END IF ;
END;

2.示例以及说明

sql如下(示例):

/**
 * 拥有对应权限项才能正常执行sql
**/
SELECT FUN_ENCRYPTION('4564879512346895654') FROM dual;
SELECT FUN_DECRYPTION('sQtqbsu/05NDCngxv/3al84bdzwtIFG91Zr6hZDpOvE=') FROM dual;

3.java程序代码以及对应说明

packagecom.fang.common.util;importlombok.extern.slf4j.Slf4j;importorg.springframework.beans.factory.annotation.Value;importorg.springframework.stereotype.Component;importsun.misc.BASE64Decoder;importsun.misc.BASE64Encoder;importjavax.crypto.Cipher;importjavax.crypto.spec.SecretKeySpec;importjava.nio.charset.StandardCharsets;/**
 * @Author LemonOvO
 * @Date 2022/8/31 10:10
 * @Version 1.0
 * @Description 对应的加密解密方法 适用项目是SpringBoot项目 加密key配置在Apollo中,若无配置可以
 * 使用静态常量写死在代码之中
 * @Project xxxx
 */@Slf4j@ComponentpublicclassAesEncoder{@Value("${database.encrypt.key:vU4C!~0_HQtlU_p@}")privatevoidsetsKey(String sKey){AesEncoder.S_KEY = sKey;}privatestaticString S_KEY;// 加密publicstaticStringencrypt(String sSrc)throwsException{if(Utils.isBlank(sSrc)){return sSrc;}if(S_KEY ==null){System.out.print("Key为空null");returnnull;}// 判断Key是否为16位if(S_KEY.length()!=16){System.out.print("Key长度不是16位");returnnull;}byte[] raw = S_KEY.getBytes(StandardCharsets.UTF_8);SecretKeySpec skeySpec =newSecretKeySpec(raw,"AES");//"算法/模式/补码方式"Cipher cipher =Cipher.getInstance("AES/ECB/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, skeySpec);byte[] encrypted = cipher.doFinal(sSrc.getBytes(StandardCharsets.UTF_8));//此处使用BASE64做转码功能,同时能起到2次加密的作用。returnnewBASE64Encoder().encode(encrypted);}// 解密publicstaticStringdecrypt(String sSrc)throwsException{try{// 判断Key是否正确if(S_KEY ==null){System.out.print("Key为空null");returnnull;}// 判断Key是否为16位if(S_KEY.length()!=16){System.out.print("Key长度不是16位");returnnull;}byte[] raw = S_KEY.getBytes(StandardCharsets.UTF_8);SecretKeySpec skeySpec =newSecretKeySpec(raw,"AES");Cipher cipher =Cipher.getInstance("AES/ECB/PKCS5Padding");
            cipher.init(Cipher.DECRYPT_MODE, skeySpec);//先用base64解密byte[] encrypted1 =newBASE64Decoder().decodeBuffer(sSrc);try{byte[] original = cipher.doFinal(encrypted1);returnnewString(original,StandardCharsets.UTF_8);}catch(Exception e){
                log.error("数据库解密失败:", e);returnnull;}}catch(Exception ex){
            log.error("数据库解密失败:", ex);returnnull;}}/**
     * 加密字符
     *
     * @param source 来源字符串   例:17799999999
     * @param begin  字符串加密开头保留的明文长度  例:3
     * @param end    字符串加密结尾处保留的明文长度  例:4
     * @return 加密后结果  例:177****9999
     */publicstaticStringencryptString(String source,Integer begin,Integer end){if(Utils.isBlank(source)){return source;}int length = source.length();if(begin >= length){returnencryptRule(source);}if(begin <0){
            begin =0;}if(end <0){
            end =0;}char[] chars = source.toCharArray();char[] result =newchar[chars.length];for(int i =0; i < chars.length; i++){if(i >= begin){if(i >=(length - end)){
                    result[i]= chars[i];}else{
                    result[i]='*';}}else{
                result[i]= chars[i];}}String encrypt =String.valueOf(result);if(encrypt.contains("*")){return encrypt;}else{returnencryptRule(encrypt);}}privatestaticStringencryptRule(String source){char[] chars = source.toCharArray();StringBuilder stringBuilder =newStringBuilder();for(int i =0; i < chars.length; i++){
            stringBuilder.append("*");}return stringBuilder.toString();}publicstaticvoidmain(String[] args)throwsException{/*
         * 此处使用AES-128-ECB加密模式,key需要为16位。
         */String cKey ="GISQvI1Wk@@Lz7%?";// 需要加密的字串String cSrc ="zhangsan";System.out.println(cSrc);// 加密String enString =AesEncoder.encrypt(cSrc);System.out.println("加密后的字串是:"+ enString);// 解密String deString =AesEncoder.decrypt(enString);System.out.println("解密后的字串是:"+ deString);}}

总结

参考文献地址:Mysql Oracle java 通用aes加密

标签: 数据库 oracle java

本文转载自: https://blog.csdn.net/weixin_44412327/article/details/126724042
版权归原作者 柠檬酸不酸OvO 所有, 如有侵权,请联系我们删除。

“数据库加密AES 适用 Mysql Oracle 以及java”的评论:

还没有评论