• 首页
  • css3教程
  • html5教程
  • jQuery手册
  • vue手册
  • php手册
  • MySQL手册
  • apache手册
  • redis手册
  • 加密和压缩函数

    表加密功能

    名称描述
    AES_DECRYPT()使用AES解密
    AES_ENCRYPT()使用AES加密
    ASYMMETRIC_DECRYPT()使用私钥或公钥解密密文
    ASYMMETRIC_DERIVE()从非对称密钥派生对称密钥
    ASYMMETRIC_ENCRYPT()使用私钥或公钥加密明文
    ASYMMETRIC_SIGN()从摘要生成签名
    ASYMMETRIC_VERIFY()验证签名与摘要匹配
    COMPRESS()以二进制字符串形式返回结果
    CREATE_ASYMMETRIC_PRIV_KEY()创建私钥
    CREATE_ASYMMETRIC_PUB_KEY()创建公钥
    CREATE_DH_PARAMETERS()生成共享的DH机密
    CREATE_DIGEST()从字符串生成摘要
    MD5()计算MD5校验和
    RANDOM_BYTES()返回一个随机字节向量
    SHA1()SHA()计算SHA-1 160位校验和
    SHA2()计算SHA-2校验和
    STATEMENT_DIGEST()计算语句摘要哈希值
    STATEMENT_DIGEST_TEXT()计算归一化语句摘要
    UNCOMPRESS()解压字符串压缩
    UNCOMPRESSED_LENGTH()返回压缩前的字符串长度
    VALIDATE_PASSWORD_STRENGTH()确定密码强度

    许多加密和压缩函数返回字符串,其结果可能包含任意字节值。如果要存储这些结果,请使用具有VARBINARYBLOB二进制字符串数据类型的列。这将避免与后空间移除或字符集转换,将改变的数据值,例如,如果使用非二进制字符串数据类型,可能会出现(潜在的问题CHARVARCHARTEXT)。

    一些加密函数返回ASCII字符的字符串:MD5()SHA()SHA1()SHA2()STATEMENT_DIGEST()STATEMENT_DIGEST_TEXT()。它们的返回值是一个字符串,具有由character_set_connectioncollation_connection系统变量确定的字符集和校验规则。除非字符集为,否则这是一个非二进制字符串binary

    如果应用程序存储来自诸如MD5()SHA1()返回十六进制数字字符串之类的函数的值,则可以通过使用将十六进制表示形式转换为二进制UNHEX()并将结果存储在列中来获得更有效的存储和比较。每对十六进制数字都需要二进制形式的一个字节,因此的值取决于十六进制字符串的长度。值是16,值是20 。对于,其范围为28到32,具体取决于指定结果所需位长的参数。BINARY(N)NNMD5()SHA1()SHA2()N

    将十六进制字符串存储在CHAR列中的大小损失至少为两倍,如果将值存储在使用utf8字符集的列中(每个字符使用4个字节),则该损失最多为八倍。由于较大的值以及需要考虑字符集校验规则,因此存储字符串还会导致比较慢。

    假设应用程序将MD5()字符串值存储在CHAR(32)列中:

    CREATE TABLE md5_tbl (md5_val CHAR(32), ...);
    INSERT INTO md5_tbl (md5_val, ...) VALUES(MD5('abcdef'), ...);
    

    要将十六进制字符串转换为更紧凑的形式,请修改应用程序以使用UNHEX()BINARY(16)如下所示:

    CREATE TABLE md5_tbl (md5_val BINARY(16), ...);
    INSERT INTO md5_tbl (md5_val, ...) VALUES(UNHEX(MD5('abcdef')), ...);
    

    应用程序应该准备好处理非常罕见的情况,即哈希函数为两个不同的输入值生成相同的值。使冲突可检测的一种方法是使哈希列成为主键。

    注意

    MD5和SHA-1算法的利用已广为人知。您可能希望考虑使用本节中介绍的另一种单向加密功能,例如SHA2()

    警告

    除非使用SSL连接,否则将作为加密函数的参数提供的密码或其他敏感值作为明文发送到MySQL服务器。同样,这些值将出现在写入它们的任何MySQL日志中。为了避免这些类型的暴露,应用程序可以在将客户端的敏感值发送到服务器之前对其进行加密。相同的注意事项适用于加密密钥。为避免暴露这些情况,应用程序可以使用存储过程在服务器端对值进行加密和解密。

    • AES_DECRYPT(crypt_str,key_str[,init_vector])

      此功能使用官方的AES(高级加密标准)算法解密数据。有关更多信息,请参见AES_ENCRYPT()

      使用AES_DECRYPT()的语句对于基于语句的复制是不安全的。

    • AES_ENCRYPT(str,key_str[,init_vector])

      AES_ENCRYPT()AES_DECRYPT()实现加密,并使用官方AES(高级加密标准)算法,即以前称为数据的解密“ Rijndael算法。” AES标准允许各种密钥长度。默认情况下,这些功能以128位密钥长度实现AES。可以使用196或256位的密钥长度,如下所述。密钥长度是性能和安全性之间的折衷。

      AES_ENCRYPT()str使用密钥字符串对字符串进行加密,key_str然后返回包含加密输出的二进制字符串。使用密钥字符串AES_DECRYPT()解密加密crypt_str的字符串key_str并返回原始的纯文本字符串。如果任一函数参数为NULL,则函数返回NULL

      strcrypt_str参数可以是任何长度,并且填充被自动添加到str所以它是所要求的基于块的算法,如AES的块的倍数。该填充会被该AES_DECRYPT()功能自动删除。的长度crypt_str可以使用以下公式计算:

      16 * (trunc(string_length / 16) + 1)
      

      对于128位的密钥长度,将密钥传递给key_str参数的最安全的方法是创建一个真正随机的128位值并将其作为二进制值传递。例如:

      INSERT INTO t
      VALUES (1,AES_ENCRYPT('text',UNHEX('F3229A0B371ED2D9441B830D21A390C3')));
      

      通过对密码短语进行哈希处理,可以使用密码短语生成AES密钥。例如:

      INSERT INTO t
      VALUES (1,AES_ENCRYPT('text', UNHEX(SHA2('My secret passphrase',512))));
      

      不要将密码或密码直接传递给crypt_str,请先对其进行哈希处理。本文档的早期版本建议使用前一种方法,但由于此处显示的示例更加安全,因此不再建议使用该方法。

      如果AES_DECRYPT()检测到无效数据或填充错误,则返回NULL。但是,如果输入数据或键无效,则可能AES_DECRYPT()返回非NULL值(可能是垃圾)。

      AES_ENCRYPT()AES_DECRYPT()允许控制块加密模式并采用可选的init_vector初始化向量参数:

      • 所述block_encryption_mode系统变量控制用于基于块的加密算法的模式。其默认值为aes-128-ecb,表示使用128位密钥长度和ECB模式进行加密。有关此变量的允许值的说明,请参见“服务器系统变量”。
      • 可选init_vector参数为需要它的块加密模式提供初始化向量。

      对于需要可选init_vector参数的模式,它必须为16个字节或更长(超过16个字节的字节将被忽略)。如果init_vector丢失,则会发生错误。

      对于不需要的模式init_vector,将忽略它,并且如果指定了警告,则会生成警告。

      可以通过调用生成用于初始化向量的随机字节字符串RANDOM_BYTES(16)。对于需要初始化向量的加密模式,必须将相同的向量用于加密和解密。

      mysql> SET block_encryption_mode = 'aes-256-cbc';
      mysql> SET @key_str = SHA2('My secret passphrase',512);
      mysql> SET @init_vector = RANDOM_BYTES(16);
      mysql> SET @crypt_str = AES_ENCRYPT('text',@key_str,@init_vector);
      mysql> SELECT AES_DECRYPT(@crypt_str,@key_str,@init_vector);
      +-----------------------------------------------	+
      | AES_DECRYPT(@crypt_str,@key_str,@init_vector) 	|
      +-----------------------------------------------	+
      | text                                          	|
      +-----------------------------------------------	+
      

      下表列出了每种允许的块加密模式以及是否需要初始化向量参数。

      块加密模式需要初始化向量
      欧洲央行没有
      哥伦比亚广播公司
      CFB1
      CFB8
      CFB128
      银行

      对于基于语句的复制使用AES_ENCRYPT()AES_DECRYPT()不安全的语句。

    • COMPRESS(string_to_compress)

      压缩字符串并将结果作为二进制字符串返回。此函数要求MySQL已使用诸如的压缩库进行编译zlib。否则,返回值始终为NULL。压缩的字符串可以使用进行解压缩UNCOMPRESS()

      mysql> SELECT LENGTH(COMPRESS(REPEAT('a',1000)));
      -> 21
      mysql> SELECT LENGTH(COMPRESS(''));
      -> 0
      mysql> SELECT LENGTH(COMPRESS('a'));
      -> 13
      mysql> SELECT LENGTH(COMPRESS(REPEAT('a',16)));
      -> 15
      

      压缩的字符串内容按以下方式存储:

      • 空字符串存储为空字符串。
      • 非空字符串存储为未压缩字符串的4字节长度(低字节在前),然后是压缩字符串。如果字符串以空格结尾,.则应添加一个额外的字符,以免将结果存储在a CHARVARCHAR列中时进行尾部修剪。(但是,不建议使用非二进制字符串数据类型(例如CHARVARCHAR存储压缩字符串),因为可能会发生字符集转换。请改用a VARBINARYBLOB二进制字符串列。)
    • MD5(str)

      计算字符串的MD5 128位校验和。该值以32个十六进制数字的字符串返回,或者NULL如果参数为NULL。例如,该返回值可用作哈希键。请参阅本节开头有关有效存储哈希值的注释。

      返回值是连接字符集中的字符串。

      如果启用了FIPS模式,则MD5()返回NULL。请参见“ FIPS支持”。

      mysql> SELECT MD5('testing');
      -> 'ae2b1fca515949e5d54fb22b8ed95575'
      

      这是“ RSA Data Security,Inc. MD5消息摘要算法。”

      请参阅本节开头有关MD5算法的注释。

    • RANDOM_BYTES(len)

      此函数返回len使用SSL库的随机数生成器生成的随机字节的二进制字符串。允许的值len范围是1到1024。超出该范围的值会发生错误。

      RANDOM_BYTES()可用于为AES_DECRYPT()AES_ENCRYPT()函数提供初始化向量。为了在这种情况下使用,len必须至少为16。允许使用较大的值,但忽略超过16的字节。

      RANDOM_BYTES()生成一个随机值,这使得其结果不确定。因此,使用此功能的语句对于基于语句的复制是不安全的。

    • SHA1(str)SHA(str)

      如RFC 3174(安全哈希算法)中所述,为字符串计算SHA-1 160位校验和。该值以40个十六进制数字的字符串形式返回,或者NULL参数为NULL。此功能的可能用途之一是作为哈希键。请参阅本节开头有关有效存储哈希值的注释。SHA()是的同义词SHA1()

      返回值是连接字符集中的字符串。

      mysql> SELECT SHA1('abc');
      -> 'a9993e364706816aba3e25717850c26c9cd0d89d'
      

      SHA1()在密码上可以被认为更安全MD5()。但是,请参阅本节开头有关MD5和SHA-1算法的注释。

    • SHA2(str,hash_length)

      计算SHA-2系列哈希函数(SHA-224,SHA-256,SHA-384和SHA-512)。第一个参数是要哈希的纯文本字符串。第二个参数表示结果的所需位长,该位的值必须为224、256、384、512或0(等于256)。如果任一参数为NULL或哈希长度不是允许值之一,则返回值为NULL。否则,函数结果是一个包含所需位数的哈希值。请参阅本节开头有关有效存储哈希值的注释。

      返回值是连接字符集中的字符串。

      mysql> SELECT SHA2('abc', 224);
      -> '23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7'
      

      仅当MySQL已配置有SSL支持时,此功能才有效。请参见“使用加密的连接”。

      SHA2()可以认为在密码上比MD5()或更安全SHA1()

    • STATEMENT_DIGEST(statement)

      给定一个SQL语句为字符串,则返回该语句摘要哈希值作为连接字符集中的字符串,或者NULL如果参数为NULL。相关STATEMENT_DIGEST_TEXT()函数返回规范化的语句摘要。有关语句摘要的信息,请参见“性能模式语句摘要和采样”。

      这两个函数都使用MySQL解析器来解析该语句。如果解析失败,则会发生错误。仅当该语句以文字字符串形式提供时,错误消息才包含解析错误。

      max_digest_length系统变量决定用于计算归一化的语句消化提供给这些功能的最大字节数。

      mysql> SET @stmt = 'SELECT * FROM mytable WHERE cola = 10 AND colb = 20';
      mysql> SELECT STATEMENT_DIGEST(@stmt);
      +------------------------------------------------------------------	+
      | STATEMENT_DIGEST(@stmt)                                          	|
      +------------------------------------------------------------------	+
      | 3bb95eeade896657c4526e74ff2a2862039d0a0fe8a9e7155b5fe492cbd78387 	|
      +------------------------------------------------------------------	+
      mysql> SELECT STATEMENT_DIGEST_TEXT(@stmt);
      +----------------------------------------------------------	+
      | STATEMENT_DIGEST_TEXT(@stmt)                             	|
      +----------------------------------------------------------	+
      | SELECT * FROM `mytable` WHERE `cola` = ? AND `colb` = ?  	|
      +----------------------------------------------------------	+
      
    • STATEMENT_DIGEST_TEXT(statement)

      给定一条SQL语句作为字符串,NULL如果连接字符集中的参数为,则以字符串形式返回规范化的语句摘要NULL。有关其他讨论和示例,请参见相关STATEMENT_DIGEST()功能的描述。

    • UNCOMPRESS(string_to_uncompress)

      解压缩由COMPRESS()函数压缩的字符串。如果参数不是压缩值,则结果为NULL。此函数要求MySQL已使用诸如的压缩库进行编译zlib。否则,返回值始终为NULL

      mysql> SELECT UNCOMPRESS(COMPRESS('any string'));
      -> 'any string'
      mysql> SELECT UNCOMPRESS('any string');
      -> NULL
      
    • UNCOMPRESSED_LENGTH(compressed_string)

      返回压缩字符串在压缩前的长度。

      mysql> SELECT UNCOMPRESSED_LENGTH(COMPRESS(REPEAT('a',30)));
      -> 30
      
    • VALIDATE_PASSWORD_STRENGTH(str)

      给定一个表示明文密码的参数,此函数返回一个整数以指示密码的强度。返回值的范围是0(弱)到100(强)。

      密码评估由组件VALIDATE_PASSWORD_STRENGTH()完成validate_password。如果未安装该组件,该函数将始终返回0。有关安装的信息validate_password,请参见“密码验证组件”。要检查或配置影响密码测试的参数,请检查或设置由实施的系统变量validate_password。请参见“密码验证选项和变量”。

      密码受到越来越严格的测试,返回值反映了满足了哪些测试,如下表所示。此外,如果validate_password.check_user_name启用了系统变量并且密码与用户名匹配,则VALIDATE_PASSWORD_STRENGTH()无论其他validate_password系统变量如何设置,都将返回0 。

      密码测试返回值
      长度<40
      长度≥4并且<validate_password.length25
      满足政策1(LOW50
      满足政策2(MEDIUM75
      满足政策3(STRONG100