一、加密算法选择

密码学中两种常见的密码算法为:对称密码算法和非对称密码算法。

对称密钥加密,又称私钥加密,即信息的发送方和接收方用一个密钥去加密和解密数据。它的最大优势是加/解密速度快,适合于对大数据量进行加密,但密钥管理困难。

非对称密钥加密,又称公钥密钥加密。它需要使用一对密钥来分别完成加密和解密操作,一个公开发布,即公开密钥,另一个由用户自己秘密保存,即私用密钥。信息发送者用公开密钥去加密,而信息接收者则用私用密钥去解密。公钥机制灵活,但加密和解密速度却比对称密钥加密慢得多。

对称加密算法用来对敏感数据等信息进行加密,常用的算法包括:
DES(Data Encryption Standard):数据加密标准,速度较快,适用于加密大量数据的场合。
3DES(Triple DES):是基于DES,对一块数据用三个不同的密钥进行三次加密,强度更高。
AES(Advanced Encryption Standard):高级加密标准,是下一代的加密算法标准,速度快,安全级别高;

Mysql官网手册

https://dev.mysql.com/doc/refman/5.7/en/encryption-functions.html#function_aes-encrypt

MySQL的内置加密函数里已经不推荐DES算法,所以选用AES算法来加解密账号密码。

二、加密策略

AES算法加解密都需要同一个key,如果这个key用来加密所有账号的密码,那么密码相同的不同账号得到的加密结果是相同的,这样会降低安全性,所以用可以唯一标识账号的aid来当做key,为了更不容易反向推导出key,实际应用中会用一个内部的salt字符串拼上账号aid来作为key。

三、实现

为了灵活和重用,没使用MySQL内置函数,改用Java实现。

AES算法实现与操作系统有关,本实现兼容Windows/Linux。

加密后获得的是byte[]类型结果,因此数据库内相应字段的类型应为BLOB,节省空间用TinyBlob类型就够。

加密算法需要使用外部类库javabase64-1.3.1.jar百度网盘下载链接

Java实现有两个类:

AESUtils:提供加解密静态方法

Base64Utils :辅助AESUtils类

AESUtils常用方法说明:

方法

返回

说明

参数

getSecretKey(String seed)

String

生成key

seed: salt+aid

encrypt(byte[] data, String key)

byte[]

加密

data: 密码明文getBytes(“UTF-8”)

key: getScretKey方法结果

decrypt(byte[] data, String key)

byte[]

解密

data: 密码密文

key: getScretKey方法结果

AESUtils.java:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.Key;
import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
public class AESUtils {
    private static final String ALGORITHM = "AES";
    private static final int KEY_SIZE = 128;
    private static final int CACHE_SIZE = 1024;
    public static String getSecretKey() throws Exception {
        return getSecretKey(null);
    }
    public static String getSecretKey(String seed) throws Exception {
        try {
            KeyGenerator _generator = KeyGenerator.getInstance(ALGORITHM);
            SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
            secureRandom.setSeed(seed.getBytes("UTF-8"));
            _generator.init(KEY_SIZE, secureRandom);
            SecretKey secretKey = _generator.generateKey();
            return Base64Utils.encode(secretKey.getEncoded());
        catch (Exception e) {
            throw new RuntimeException("初始化密钥出现异常");
        }
    }
    public static byte[] encrypt(byte[] data, String key) throws Exception {
        Key k = toKey(Base64Utils.decode(key));
        byte[] raw = k.getEncoded();
        SecretKeySpec secretKeySpec = new SecretKeySpec(raw, ALGORITHM);
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
        return cipher.doFinal(data);
    }
    public static void encryptFile(String key, String sourceFilePath, String destFilePath) throws Exception {
        File sourceFile = new File(sourceFilePath);
        File destFile = new File(destFilePath);
        if (sourceFile.exists() && sourceFile.isFile()) {
            if (!destFile.getParentFile().exists()) {
                destFile.getParentFile().mkdirs();
            }
            destFile.createNewFile();
            InputStream in = new FileInputStream(sourceFile);
            OutputStream out = new FileOutputStream(destFile);
            Key k = toKey(Base64Utils.decode(key));
            byte[] raw = k.getEncoded();
            SecretKeySpec secretKeySpec = new SecretKeySpec(raw, ALGORITHM);
            Cipher cipher = Cipher.getInstance(ALGORITHM);
            cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
            CipherInputStream cin = new CipherInputStream(in, cipher);
            byte[] cache = new byte[CACHE_SIZE];
            int nRead = 0;
            while ((nRead = cin.read(cache)) != -1) {
                out.write(cache, 0, nRead);
                out.flush();
            }
            out.close();
            cin.close();
            in.close();
        }
    }
    public static byte[] decrypt(byte[] data, String key) throws Exception {
        Key k = toKey(Base64Utils.decode(key));
        byte[] raw = k.getEncoded();
        SecretKeySpec secretKeySpec = new SecretKeySpec(raw, ALGORITHM);
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
        return cipher.doFinal(data);
    }
    public static void decryptFile(String key, String sourceFilePath, String destFilePath) throws Exception {
        File sourceFile = new File(sourceFilePath);
        File destFile = new File(destFilePath);
        if (sourceFile.exists() && sourceFile.isFile()) {
            if (!destFile.getParentFile().exists()) {
                destFile.getParentFile().mkdirs();
            }
            destFile.createNewFile();
            FileInputStream in = new FileInputStream(sourceFile);
            FileOutputStream out = new FileOutputStream(destFile);
            Key k = toKey(Base64Utils.decode(key));
            byte[] raw = k.getEncoded();
            SecretKeySpec secretKeySpec = new SecretKeySpec(raw, ALGORITHM);
            Cipher cipher = Cipher.getInstance(ALGORITHM);
            cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
            CipherOutputStream cout = new CipherOutputStream(out, cipher);
            byte[] cache = new byte[CACHE_SIZE];
            int nRead = 0;
            while ((nRead = in.read(cache)) != -1) {
                cout.write(cache, 0, nRead);
                cout.flush();
            }
            cout.close();
            out.close();
            in.close();
        }
    }
    private static Key toKey(byte[] key) throws Exception {
        SecretKey secretKey = new SecretKeySpec(key, ALGORITHM);
        return secretKey;
    }
}

Base64Utils.java:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
import it.sauronsoftware.base64.Base64;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
public class Base64Utils {
    private static final int CACHE_SIZE = 1024;
    public static byte[] decode(String base64) throws Exception {
        return Base64.decode(base64.getBytes("UTF-8"));
    }
    public static String encode(byte[] bytes) throws Exception {
        return new String(Base64.encode(bytes));
    }
    public static String encodeFile(String filePath) throws Exception {
        byte[] bytes = fileToByte(filePath);
        return encode(bytes);
    }
    public static void decodeToFile(String filePath, String base64) throws Exception {
        byte[] bytes = decode(base64);
        byteArrayToFile(bytes, filePath);
    }
    public static byte[] fileToByte(String filePath) throws Exception {
        byte[] data = new byte[0];
        File file = new File(filePath);
        if (file.exists()) {
            FileInputStream in = new FileInputStream(file);
            ByteArrayOutputStream out = new ByteArrayOutputStream(2048);
            byte[] cache = new byte[CACHE_SIZE];
            int nRead = 0;
            while ((nRead = in.read(cache)) != -1) {
                out.write(cache, 0, nRead);
                out.flush();
            }
            out.close();
            in.close();
            data = out.toByteArray();
        }
        return data;
    }
    public static void byteArrayToFile(byte[] bytes, String filePath) throws Exception {
        InputStream in = new ByteArrayInputStream(bytes);
        File destFile = new File(filePath);
        if (!destFile.getParentFile().exists()) {
            destFile.getParentFile().mkdirs();
        }
        destFile.createNewFile();
        OutputStream out = new FileOutputStream(destFile);
        byte[] cache = new byte[CACHE_SIZE];
        int nRead = 0;
        while ((nRead = in.read(cache)) != -1) {
            out.write(cache, 0, nRead);
            out.flush();
        }
        out.close();
        in.close();
    }
}

本文转自   zl1030   51CTO博客,原文链接:http://blog.51cto.com/zl1030/1656283

账号密码数据库加密说明相关推荐

  1. 使用selenium进行密码破解(绕过账号密码JS加密)

    经常碰到网站,账号密码通过js加密后进行提交.通过burp拦截抓到的账号密码是加密后的,所以无法通过burp instruder进行破解.只能模拟浏览器填写表单并点击登录按钮进行破解.于是想到了自动化 ...

  2. mysql数据库表添加加密密码_数据库账号密码加密详解及实例

    数据库账号密码加密详解及实例 数据库中经常有对数据库账号密码的加密,但是碰到一个问题,在使用UserService对密码进行加密的时候,spring security 也是需要进行同步配置的,因为sp ...

  3. SSM数据库账号密码加密

    使用SSM框架开发WEB项目时,数据库的账号密码一般会写在dbconfig.properties里,为了做到保护版权等效果,要对数据库账号密码进行加密,一共有分为三步. 一.创建DESUtil类 提供 ...

  4. 使用RSA加密传输账号密码信息

    原文地址:https://blog.springcoder.cn/posts/5b7ae417.html 背景 在开发中,通常会偷懒将用户的登录信息(账号密码)直接以明文的方式发送到后端,但我们的项目 ...

  5. python实现账号密码登录

    用Python实现账号密码登录 准备 无需数据库 程序简介 运行这个程序,注册后哪怕重新运行,注册的账号依然存在,我们可以把账号密码分别保存到2个txt中,使用的时候再读取txt 为了安全起见,我们可 ...

  6. 清除WIN2000中的Administrator账号密码

    Windows 2000所在的WinntSystem32Config目录下有个SAM文件(即账号密码数据库文件),它保存了Windows 2000中所有的用户名和密码.当你登录的时候,系统就会把你键入 ...

  7. 【Jasypt】Java 轻量级加密工具实现代码数据库账号密码加密

    前言 对很多人来说,项目中习惯会把数据库的账号密码直接用明文写在配置文件中,其实这样并不是特别好,虽然是方便查看,但是也不太安全.所以这篇文章主要是一款轻量级加密工具的使用介绍. 参考资料 Jasyp ...

  8. 如何查看服务器账户密码信息文件,如何查询服务器的数据库账号密码

    如何查询服务器的数据库账号密码 内容精选 换一换 华为云提供两种连接方式通过SQL Server客户端连接实例:非SSL连接和SSL连接.其中,SSL连接实现了数据加密功能,具有更高的安全性.准备弹性 ...

  9. 破解Navicat Premium数据库账号密码

    破解Navicat Premium数据库账号密码 如果你想破解一个已经连接好的数据库密码,可以参考这个方法. 邮件查看已经连接好的数据库属性是这样的 但是密码是******谁也看不懂,博主也从网站上下 ...

最新文章

  1. Java项目:电商书城平台系统设计和实现(java+springboot+mysql+spring+jsp)
  2. ORACLE8对象模型
  3. 借助Scrum工作室使用敏捷原则提升组织响应能力
  4. maven error in opening zip file报错解决
  5. 搜索引擎排名不友好的五个地点-SEO
  6. 深入理解STM32内存管理
  7. C#得到CPU的序列号、硬盘序列号、网卡序列号
  8. python导入函数模块 为什么会打印两次_5.1.2Python从模块导入函数
  9. c语言简易成绩管理系统c语言,C语言写的简易成绩管理系统
  10. 只限女生!谷歌 2020 Women Techmakers 奖学金项目申请开启!
  11. 云图说|知道吗?在和你对话的那头,也许是个机器人哦~
  12. debounce(防抖)和throttle(节流)
  13. Ubunt 14.04 install Sogou input
  14. 竖版1:2500万标准中国地图
  15. Qt5构建出错问题解决办法:为项目untitled执行步骤
  16. eclipse打开中文文件乱码问题
  17. 3D LUT调色:单反如何实现电影级调色。
  18. CH0805 防线 二分
  19. java读取qq邮箱邮件
  20. 深度盘点:初学者必备这 15 个 Scikit-Learn 重要技能

热门文章

  1. python接口自动化(四十)- logger 日志 - 下(超详解)
  2. python用户界面画图_通过海龟绘图学习Python-01
  3. Windows 电脑命令一览
  4. MyBatis3源码解析(1)探索准备
  5. 五年级计算机教室使用记录,五年级班会记录.doc
  6. wamp xampp mysql端口冲突_解决xampp端口冲突
  7. Java学习之字符与ASCII码相互转换的面板设计
  8. Spring Cloud 设置Feign的日志记录级别
  9. linux awk搜索文本最后个字符串,[转载]linux下的文本处理命令sedawkgrep
  10. 启动多个线程后同时并行执行程序