digest 包

介绍

digest 包提供常用的消息摘要算法

使用本包需要外部依赖 OpenSSL 3crypto 动态库文件,故使用前需安装相关工具:

  • 对于 Linux 操作系统,可参考以下方式:
    • 如果系统的包管理工具支持安装 OpenSSL 3 开发工具包,可通过这个方式安装,并确保系统安装目录下含有 libcrypto.solibcrypto.so.3 这两个动态库文件,例如 Ubuntu 22.04 系统上可使用 sudo apt install libssl-dev 命令安装 libssl-dev 工具包;
    • 如果无法通过上面的方式安装,可自行下载 OpenSSL 3.x.x 源码编译安装软件包,并确保安装目录下含有 libcrypto.solibcrypto.so.3 这两个动态库文件,然后可选择下面任意一种方式来保证系统链接器可以找到这些文件:
      • 在系统未安装 OpenSSL 的场景,安装时选择直接安装到系统路径下;
      • 安装在自定义目录的场景,将这些文件所在目录设置到环境变量 LD_LIBRARY_PATH 以及 LIBRARY_PATH 中。
  • 对于 Windows 操作系统,可按照以下步骤:
    • 自行下载 OpenSSL 3.x.x 源码编译安装 x64 架构软件包或者自行下载安装第三方预编译的供开发人员使用的 OpenSSL 3.x.x 软件包;
    • 确保安装目录下含有 libcrypto.dll.a(或 libcrypto.lib)、libcrypto-3-x64.dll 这两个库文件;
    • libcrypto.dll.a(或 libcrypto.lib) 所在的目录路径设置到环境变量 LIBRARY_PATH 中,将 libcrypto-3-x64.dll 所在的目录路径设置到环境变量 PATH 中。
  • 对于 macOS 操作系统,可参考以下方式:
    • 使用 brew install openssl@3 安装,并确保系统安装目录下含有 libcrypto.dyliblibcrypto.3.dylib 这两个动态库文件;
    • 如果无法通过上面的方式安装,可自行下载 OpenSSL 3.x.x 源码编译安装软件包,并确保安装目录下含有 libcrypto.dyliblibcrypto.3.dylib 这两个动态库文件,然后可选择下面任意一种方式来保证系统链接器可以找到这些文件:
      • 在系统未安装 OpenSSL 的场景,安装时选择直接安装到系统路径下;
      • 安装在自定义目录的场景,将这些文件所在目录设置到环境变量 DYLD_LIBRARY_PATH 以及 LIBRARY_PATH 中。

如果未安装OpenSSL 3软件包或者安装低版本的软件包,程序可能无法使用并抛出相关异常 CryptoException: Can not load openssl library or function xxx.

主要接口

class MD5

提供 MD5 算法的实现接口。

public class MD5 <: Digest {
    public init()
}

init

public init()

功能:无参构造函数,创建 MD5 对象。

prop size

public prop size: Int64

功能:MD5 摘要信息长度,单位字节。

返回值: MD5 摘要信息的字节长度,长度为16

prop blockSize

public prop blockSize: Int64

功能:MD5 信息块长度,单位字节。

返回值:MD5 信息块的字节长度,长度为64

func write

public func write(buffer: Array<Byte>): Unit

功能:使用给定的 buffer 更新 MD5 对象,在调用 finish 前可以多次更新。

参数:

  • buffer:更新后的 MD5 字节序列

异常:

  • CryptoException: 已经调用 finish 进行摘要计算后未重置上下文,抛此异常

func finish

public func finish(): Array<Byte>

功能:返回生成的 MD5 值,注意调用 finish 后 MD5 上下文会发生改变,finish 后不可以再进行摘要计算,如重新计算需要 reset 重置上下文。

返回值:生成的 MD5 字节序列

异常:

  • CryptoException: 未重置上下文再次调用 finish 进行摘要计算,抛此异常

func reset

public func reset(): Unit

功能:重置 MD5 对象到初始状态,清理 MD5 上下文。

class SHA1

提供 SHA1 算法的实现接口。

public class SHA1 <: Digest {
    public init()
}

init

public init()

功能:无参构造函数,创建 SHA1 对象。

prop size

public prop size: Int64

功能:SHA1 摘要信息长度,单位字节。

返回值: SHA1 摘要信息的字节长度,长度为20

prop blockSize

public prop blockSize: Int64

功能:SHA1 信息块长度,单位字节。

返回值:SHA1 信息块的字节长度,长度为64

func write

public func write(buffer: Array<Byte>): Unit

功能:使用给定的 buffer 更新 SHA1 对象,在调用 finish 前可以多次更新。

参数:

  • buffer:更新后的 SHA1 字节序列

异常:

  • CryptoException: 已经调用 finish 进行摘要计算后未重置上下文,抛此异常

func finish

public func finish(): Array<Byte>

功能:返回生成的 SHA1 值,注意调用 finish 后 SHA224 上下文会发生改变,finish 后不可以再进行摘要计算,如重新计算需要 reset 重置上下文。

返回值:生成的 SHA1 字节序列

异常:

  • CryptoException: 未重置上下文再次调用 finish 进行摘要计算,抛此异常

func reset

public func reset(): Unit

功能:重置 SHA1 对象到初始状态,清理 SHA1 上下文。

class SHA224

提供 SHA224 算法的实现接口。

public class SHA224 <: Digest {
    public init()
}

init

public init()

功能:无参构造函数,创建 SHA224 对象。

prop size

public prop size: Int64

功能:SHA224 摘要信息长度,单位字节。

返回值: SHA224 摘要信息的字节长度,长度为28

prop blockSize

public prop blockSize: Int64

功能:SHA224 信息块长度,单位字节。

返回值:SHA224 信息块的字节长度,长度为64

func write

public func write(buffer: Array<Byte>): Unit

功能:使用给定的 buffer 更新 SHA224 对象,在调用 finish 前可以多次更新。

参数:

  • buffer: 更新后的 SHA224 字节序列

异常:

  • CryptoException: 已经调用 finish 进行摘要计算后未重置上下文,抛此异常

func finish

public func finish(): Array<Byte>

功能:返回生成的 SHA224 值,注意调用 finish 后 SHA224 上下文会发生改变,finish 后不可以再进行摘要计算,如重新计算需要 reset 重置上下文。

返回值:生成的 SHA224 字节序列

异常:

  • CryptoException: 未重置上下文再次调用 finish 进行摘要计算,抛此异常

func reset

public func reset(): Unit

功能:重置 SHA224 对象到初始状态,清理 SHA224 上下文。

class SHA256

提供 SHA256 算法的实现接口。

public class SHA256 <: Digest {
    public init()
}

init

public init()

功能:无参构造函数,创建 SHA256 对象。

prop size

public prop size: Int64

功能:SHA256 摘要信息长度,单位字节。

返回值: SHA256 摘要的信息字节长度,长度为32

prop blockSize

public prop blockSize: Int64

功能:SHA256 信息块长度,单位字节。

返回值:SHA256 信息块的字节长度,长度为64

func write

public func write(buffer: Array<Byte>): Unit

功能:使用给定的 buffer 更新 SHA256 对象,在调用 finish 前可以多次更新。

参数:

  • buffer: 更新后的 SHA256 字节序列

异常:

  • CryptoException: 已经调用 finish 进行摘要计算后未重置上下文,抛此异常

func finish

public func finish(): Array<Byte>

功能:返回生成的 SHA256 值,注意调用 finish 后 SHA256 上下文会发生改变,finish 后不可以再进行摘要计算,如重新计算需要 reset 重置上下文。

返回值:生成的 SHA256 字节序列

异常:

  • CryptoException: 未重置上下文再次调用 finish 进行摘要计算,抛此异常

func reset

public func reset(): Unit

功能:重置 SHA256 对象到初始状态,清理 SHA256 上下文。

class SHA384

提供 SHA384 算法的实现接口。

public class SHA384 <: Digest {
    public init()
}

init

public init()

功能:无参构造函数,创建 SHA384 对象。

prop size

public prop size: Int64

功能:SHA384 摘要信息长度,单位字节。

返回值: SHA384 摘要的信息字节长度,长度为48

prop blockSize

public prop blockSize: Int64

功能:SHA384 信息块长度,单位字节。

返回值:SHA384 信息块的字节长度,长度为128

func write

public func write(buffer: Array<Byte>): Unit

功能:使用给定的 buffer 更新 SHA384 对象,在调用 finish 前可以多次更新。

参数:

  • buffer:更新后的 SHA384 字节序列

异常:

  • CryptoException: 已经调用 finish 进行摘要计算后未重置上下文,抛此异常

func finish

public func finish(): Array<Byte>

功能:返回生成的 SHA384 值,注意调用 finish 后 SHA384 上下文会发生改变,finish 后不可以再进行摘要计算,如重新计算需要 reset 重置上下文。

返回值:生成的 SHA384 字节序列

异常:

  • CryptoException: 未重置上下文再次调用 finish 进行摘要计算,抛此异常

func reset

public func reset(): Unit

功能:重置 SHA384 对象到初始状态,清理 SHA384 上下文。

class SHA512

提供 SHA512 算法的实现接口。

public class SHA512 <: Digest {
    public init()
}

init

public init()

功能:无参构造函数,创建 SHA512 对象。

prop size

public prop size: Int64

功能:SHA512 摘要信息长度,单位字节。

返回值: SHA512 摘要信息的字节长度,长度为64

prop blockSize

public prop blockSize: Int64

功能:SHA512 信息块长度,单位字节。

返回值:SHA512 信息块的字节长度,长度为128

func write

public func write(buffer: Array<Byte>): Unit

功能:使用给定的 buffer 更新 SHA512 对象,在调用 finish 前可以多次更新。

参数:

  • buffer:更新后的 SHA512 字节序列

异常:

  • CryptoException: 已经调用 finish 进行摘要计算后未重置上下文,抛此异常

func finish

public func finish(): Array<Byte>

功能:返回生成的 SHA512 值,注意调用 finish 后 SHA512 上下文会发生改变,finish 后不可以再进行摘要计算,如重新计算需要 reset 重置上下文。

返回值:生成的 SHA512 字节序列

异常:

  • CryptoException: 未重置上下文再次调用 finish 进行摘要计算,抛此异常

func reset

public func reset(): Unit

功能:重置 SHA512 对象到初始状态,清理 SHA512 上下文。

class HMAC

提供 HMAC 算法的实现接口。

public class HMAC <: Digest {
    public init(key: Array<Byte>, algorithm: HashType)
}

init

public init(key: Array<Byte>, algorithm: HashType)

功能:构造函数,创建 HMAC 对象。

参数:key 为密钥,建议该参数不小于所选Hash算法摘要的长度,algorithm 为 hash 算法,目前仅支持 SHA512 算法

异常:

  • CryptoException: 使用 SHA512 以外的 hash 算法或 key 值为空时,抛出异常

prop size

public prop size: Int64

功能:HMAC 所选 Hash 算法的摘要信息长度,单位字节。

返回值: HMAC 所选 Hash 算法摘要信息的字节长度

prop blockSize

public prop blockSize: Int64

功能:HMAC 所选 Hash 算法信息块长度,单位字节。

返回值:HMAC 所选 Hash 算法信息块的字节长度

func write

public func write(buffer: Array<Byte>): Unit 

功能:使用给定的 buffer 更新 HMAC 对象,在调用 finish 前可以多次更新。

参数:

  • buffer:需要追加的字节序列

异常:

  • CryptoException: 当 buffer 为空、finish 已经调用生成信息摘要场景,抛此异常

func finish

public func finish(): Array<Byte>

功能:返回生成的信息摘要值,注意调用 finish 后不可以再进行摘要计算,如重新计算需要 reset 重置上下文。

返回值:生成的信息摘要字节序列

异常:

  • CryptoException: 未重置上下文再次调用 finish 进行摘要计算,抛此异常

func reset

public func reset(): Unit

功能:重置 HMAC 对象到初始状态,清理 HMAC 上下文。

异常:

  • CryptoException: 当内部错误,重置失败,抛此异常

func equal

public static func equal(mac1: Array<Byte>, mac2: Array<Byte>): Bool

功能:比较两个信息摘要是否相等,且不泄露比较时间,即比较不采用传统短路原则,从而防止 timing attack 类型的攻击。

参数:

  • mac1:需要比较的信息摘要序列
  • mac2:需要比较的信息摘要序列

返回值:信息摘要是否相同, true 相同, false 不相同

struct HashType

public struct HashType

此类为 Hash 算法类。

prop MD5

public static prop MD5: HashType

功能:返回 MD5 类型。

prop SHA1

public static prop SHA1: HashType

功能:返回 SHA1 类型。

prop SHA224

public static prop SHA224: HashType

功能:返回 SHA224 类型。

prop SHA256

public static prop SHA256: HashType

功能:返回 SHA256 类型。

prop SHA384

public static prop SHA384: HashType

功能:返回 SHA384 类型。

prop SHA512

public static prop SHA512: HashType

功能:返回 SHA512 类型。

func toString

public func toString(): String

功能:获取 Hash 算法名称。

class SM3

提供 SM3 算法的实现接口。

public class SM3 <: Digest {
    public init()
}

init

public init()

功能:无参构造函数,创建 SM3 对象。

prop size

public prop size: Int64

功能:SM3 摘要信息长度,单位字节。

返回值: SM3 摘要信息的字节长度,长度为32

prop blockSize

public prop blockSize: Int64

功能:SM3 信息块长度,单位字节。

返回值:SM3 信息块的字节长度,长度为64

func write

public func write(buffer: Array<Byte>): Unit

功能:使用给定的 buffer 更新 SM3 对象,在调用 finish 前可以多次更新。

参数:

  • buffer:更新后的 SM3 字节序列

异常:

  • CryptoException: 已经调用 finish 进行摘要计算后未重置上下文,抛此异常

func finish

public func finish(): Array<Byte>

功能:返回生成的 SM3 值,注意调用 finish 后 SM3 上下文会发生改变,finish 后不可以再进行摘要计算,如重新计算需要 reset 重置上下文。

返回值:生成的 SM3 字节序列

异常:

  • CryptoException: 未重置上下文再次调用 finish 进行摘要计算,抛此异常

func reset

public func reset(): Unit

功能:重置 SM3 对象到初始状态,清理 SM3 上下文。

class CryptoException

public class CryptoException <: Exception {
    public init()
    public init(message: String)
}

此类为 crypto 库出现错误时抛出的异常。

init

public init()

功能:无参构造函数,构造异常。

init

public init(message: String)

功能:构造异常。

参数:

  • message:异常信息

示例

MD5 算法示例

使用 MD5 算法计算摘要示例。

调用仓颉标准库提供的通用 digest 函数

from crypto import digest.*
from std import convert.*
from std import crypto.digest.*
from encoding import hex.*

main() {
    var str: String = "helloworld"
    var md5Instance = MD5()
    var md: Array<Byte> = digest(md5Instance, str)
    var result: String = toHexString(md)
    println(result)
    return 0
}

调用 MD5 成员函数

from crypto import digest.*
from std import convert.*
from std import crypto.digest.*
from encoding import hex.*

main() {
    var str: String = "helloworld"
    var md5Instance = MD5()
    md5Instance.write(str.toArray())
    var md: Array<Byte> = md5Instance.finish()
    var result: String = toHexString(md)
    println(result)
    return 0
}

运行结果如下:

fc5e038d38a57032085441e7fe7010b0

SHA1 算法示例

使用 SHA1 算法计算摘要示例。

调用仓颉标准库提供的通用 digest 函数

from crypto import digest.*
from std import convert.*
from std import crypto.digest.*
from encoding import hex.*

main() {
    var str: String = "helloworld"
    var sha1Instance = SHA1()
    var md: Array<Byte> = digest(sha1Instance, str)
    var result: String = toHexString(md)
    println(result)
    return 0
}

调用 SHA1 成员函数

from crypto import digest.*
from std import convert.*
from std import crypto.digest.*
from encoding import hex.*

main() {
    var str: String = "helloworld"
    var sha1Instance = SHA1()
    sha1Instance.write(str.toArray())
    var md: Array<Byte> = sha1Instance.finish()
    var result: String = toHexString(md)
    println(result)
    return 0
}

运行结果如下:

6adfb183a4a2c94a2f92dab5ade762a47889a5a1

SHA224 算法示例

使用 SHA224 算法计算摘要示例。

调用仓颉标准库提供的通用 digest 函数

from crypto import digest.*
from std import convert.*
from std import crypto.digest.*
from encoding import hex.*

main() {
    var str: String = "helloworld"
    var sha224Instance = SHA224()
    var md: Array<Byte> = digest(sha224Instance, str)
    var result: String = toHexString(md)
    println(result)
    return 0
}

调用 SHA224 成员函数

from crypto import digest.*
from std import convert.*
from std import crypto.digest.*
from encoding import hex.*

main() {
    var str: String = "helloworld"
    var sha224Instance = SHA224()
    sha224Instance.write(str.toArray())
    var md: Array<Byte> = sha224Instance.finish()
    var result: String = toHexString(md)
    println(result)
    return 0
}

运行结果如下:

b033d770602994efa135c5248af300d81567ad5b59cec4bccbf15bcc

SHA256 算法示例

使用 SHA256 算法计算摘要示例。

调用仓颉标准库提供的通用 digest 函数

from crypto import digest.*
from std import convert.*
from std import crypto.digest.*
from encoding import hex.*

main() {
    var str: String = "helloworld"
    var sha256Instance = SHA256()
    var md: Array<Byte> = digest(sha256Instance, str)
    var result: String = toHexString(md)
    println(result)
    return 0
}

调用 SHA256 成员函数

from crypto import digest.*
from std import convert.*
from std import crypto.digest.*
from encoding import hex.*

main() {
    var str: String = "helloworld"
    var sha256Instance = SHA256()
    sha256Instance.write(str.toArray())
    var md: Array<Byte> = sha256Instance.finish()
    var result: String = toHexString(md)
    println(result)
    return 0
}

运行结果如下:

936a185caaa266bb9cbe981e9e05cb78cd732b0b3280eb944412bb6f8f8f07af

SHA384 算法示例

使用 SHA384 算法计算摘要示例。

调用仓颉标准库提供的通用 digest 函数

from crypto import digest.*
from std import convert.*
from std import crypto.digest.*
from encoding import hex.*

main() {
    var str: String = "helloworld"
    var sha384Instance = SHA384()
    var md: Array<Byte> = digest(sha384Instance, str)
    var result: String = toHexString(md)
    println(result)
    return 0
}

调用 SHA384 成员函数

from crypto import digest.*
from std import convert.*
from std import crypto.digest.*
from encoding import hex.*

main() {
    var str: String = "helloworld"
    var sha384Instance = SHA384()
    sha384Instance.write(str.toArray())
    var md: Array<Byte> = sha384Instance.finish()
    var result: String = toHexString(md)
    println(result)
    return 0
}

运行结果如下:

97982a5b1414b9078103a1c008c4e3526c27b41cdbcf80790560a40f2a9bf2ed4427ab1428789915ed4b3dc07c454bd9

SHA512 算法示例

使用 SHA512 算法计算摘要示例。

调用仓颉标准库提供的通用 digest 函数

from crypto import digest.*
from std import convert.*
from std import crypto.digest.*
from encoding import hex.*

main() {
    var str: String = "helloworld"
    var sha512Instance = SHA512()
    var md: Array<Byte> = digest(sha512Instance, str)
    var result: String = toHexString(md)
    println(result)
    return 0
}

调用 SHA512 成员函数

from crypto import digest.*
from std import convert.*
from std import crypto.digest.*
from encoding import hex.*

main() {
    var str: String = "helloworld"
    var sha512Instance = SHA512()
    sha512Instance.write(str.toArray())
    var md: Array<Byte> = sha512Instance.finish()
    var result: String = toHexString(md)
    println(result)
    return 0
}

运行结果如下:

1594244d52f2d8c12b142bb61f47bc2eaf503d6d9ca8480cae9fcf112f66e4967dc5e8fa98285e36db8af1b8ffa8b84cb15e0fbcf836c3deb803c13f37659a60

HMAC 算法示例

使用 HMAC-SHA512 算法计算摘要示例。

调用仓颉标准库提供的通用 digest 函数

from crypto import digest.*
from encoding import hex.*
from std import crypto.digest.*
 
main() {
    var algorithm: HashType  =  HashType.SHA512
    var key: Array<UInt8> = "cangjie".toArray()
    var data: Array<UInt8> = "123456789".toArray()
    var hmac= HMAC(key,algorithm)
    var md: Array<Byte> = digest(hmac, data)
    var result: String = toHexString(md)
    println(result)
    return 0
}

运行结果如下:

2bafeb53b60a119d38793a886c7744f5027d7eaa3702351e75e4ff9bf255e3ce296bf41f80adda2861e81bd8efc52219df821852d84a17fb625e3965ebf2fdd9

调用 HMAC-SHA512 成员函数

from crypto import digest.*
from encoding import hex.*
 
main() {
    var algorithm: HashType  =  HashType.SHA512
    var key: Array<UInt8> = "cangjie".toArray()
    var data1: Array<UInt8> = "123".toArray()
    var data2: Array<UInt8> = "456".toArray()
    var data3: Array<UInt8> = "789".toArray()
    var data4: Array<UInt8> = "123456789".toArray()
    var hmac= HMAC(key,algorithm)
    hmac.write(data1)
    hmac.write(data2)
    hmac.write(data3)
    var md1: Array<Byte>= hmac.finish()
    var result1: String = toHexString(md1)
    println(result1)
 
    hmac.reset()
    hmac.write(data4)
    var md2: Array<Byte>= hmac.finish()
    var result2: String = toHexString(md2)
    println(result2)
    println(HMAC.equal(md1,md2))
    return 0
}

运行结果如下:

2bafeb53b60a119d38793a886c7744f5027d7eaa3702351e75e4ff9bf255e3ce296bf41f80adda2861e81bd8efc52219df821852d84a17fb625e3965ebf2fdd9
2bafeb53b60a119d38793a886c7744f5027d7eaa3702351e75e4ff9bf255e3ce296bf41f80adda2861e81bd8efc52219df821852d84a17fb625e3965ebf2fdd9
true

SM3 算法示例

使用 SM3 算法计算摘要示例。

调用仓颉标准库提供的通用 digest 函数

from crypto import digest.*
from std import convert.*
from std import crypto.digest.*
from encoding import hex.*

main() {
    var str: String = "helloworld"
    var sm3Instance = SM3()
    var md: Array<Byte> = digest(sm3Instance, str)
    var result: String = toHexString(md)
    println(result)
    return 0
}