神奇的 Zig、C 和 OpenSSL

本文介绍了如何使用 Zig 编程语言和 OpenSSL 库进行集成,以实现包括 MD5、SHA1、SHA-256 等多种哈希算法。文章提供了 Zig 代码示例,展示了如何调用 OpenSSL 的 EVP 接口来计算哈希值,并提供了在 Windows 环境下编译和运行该代码的步骤。

神奇的 Zig、C 和 OpenSSL

OpenSSL 是网络安全的瑞士军刀,每当我们需求检查哈希值或数字签名时,我们经常求助于 OpenSSL。 基本上,它为我们提供了密码学的“零点”真相。 但是,与它集成可能有点麻烦,并可能导致处理内存的问题。 但是 Zig 编程语言为我们提供了一种现代语言,可以应对这种集成,同时消除编译和链接 C 代码的一些复杂性。 那么,让我们将 Zig 与 OpenSSL 集成起来。

Zig 是一种相对较新的编程语言,使用起来很简单。 它的优势之一是可以与现有的 C 代码集成。 在这种情况下,我们将与 OpenSSL 库集成,并运用 evp.h 的 OpenSSL 头文件来编译我们的代码,然后与 libcrypto.lib 库集成。

为了编译代码,我们需要 evp.h 的 C 头文件:

const c = @cImport({
    @cInclude("openssl/evp.h");
});

然后我们可以与以下内容集成:

const md5 = c.EVP_get_digestbyname("md5");

然后我们可以创建一个指向 unsigned int 的 C 指针,如下所示:

const hash_length: [*c]c_uint = 0;

我们的数据也可以被指定为指向字符串的 C 指针:

var data: [*c]u8 = undefined;

编码如下:

var data: [*c]u8 = undefined;
    const md5 = c.EVP_get_digestbyname("md5");

const context = c.EVP_MD_CTX_create();

    const hash_length: [*c]c_uint = 0;
    _ = c.EVP_DigestInit(context, md5);
    _ = c.EVP_DigestUpdate(context, data, len);
    var md5hash: [16]u8 = undefined;
    _ = c.EVP_DigestFinal(context, &md5hash, hash_length);
    try stdout.print("Data:\t\t{s}\n\n", .{data});
    try stdout.print("MD5:\t\t{x}\n", .{md5hash});

其中 md5hash 将包含 16 字节(128 位)的哈希值。

源代码

以下代码运用 Zig Version 0.15.1 编译 [ 这里]。 我们将与 OpenSSL 集成以生成一系列哈希方法,例如 MD5、SHA1 和 SHA-256 [ 这里]:

const std = @import("std");

const c = @cImport({
    @cInclude("openssl/evp.h");
});
pub fn main() !void {
    var stdout_buffer: [4096]u8 = undefined;
    var stdout_writer = std.fs.File.stdout().writer(&stdout_buffer);
    const stdout = &stdout_writer.interface;
    var data: [*c]u8 = undefined;
    const args = try std.process.argsAlloc(std.heap.page_allocator);
    defer std.process.argsFree(std.heap.page_allocator, args);

    // 检查是否有任何参数
    if (args.len > 1) {
        data = args[1];
    }
    const len: usize = args[1].len;
    const md5 = c.EVP_get_digestbyname("md5");
    const sha1 = c.EVP_get_digestbyname("sha1");
    const sha256 = c.EVP_get_digestbyname("sha256");
    const sha512 = c.EVP_get_digestbyname("sha512");
    const blake2s256 = c.EVP_get_digestbyname("blake2s256");
    const sha3_256 = c.EVP_get_digestbyname("sha3-256");
    const sm3 = c.EVP_get_digestbyname("sm3");
    const context = c.EVP_MD_CTX_create();
    const hash_length: [*c]c_uint = 0;

    // MD5
    _ = c.EVP_DigestInit(context, md5);
    _ = c.EVP_DigestUpdate(context, data, len);
    var md5hash: [16]u8 = undefined;
    _ = c.EVP_DigestFinal(context, &md5hash, hash_length);

    // SHA1
    _ = c.EVP_DigestInit(context, sha1);
    _ = c.EVP_DigestUpdate(context, data, len);
    var sha1hash: [20]u8 = undefined;
    _ = c.EVP_DigestFinal(context, &sha1hash, hash_length);

    // SHA256
    _ = c.EVP_DigestInit(context, sha256);
    _ = c.EVP_DigestUpdate(context, data, len);
    var sha256hash: [32]u8 = undefined;
    _ = c.EVP_DigestFinal(context, &sha256hash, hash_length);

    // SHA512
    _ = c.EVP_DigestInit(context, sha512);
    _ = c.EVP_DigestUpdate(context, data, len);
    var sha512hash: [64]u8 = undefined;
    _ = c.EVP_DigestFinal(context, &sha512hash, hash_length);

    // blake2s256
    _ = c.EVP_DigestInit(context, blake2s256);
    _ = c.EVP_DigestUpdate(context, data, len);
    var blake2s256hash: [32]u8 = undefined;
    _ = c.EVP_DigestFinal(context, &blake2s256hash, hash_length);

    // SHA3-256
    _ = c.EVP_DigestInit(context, sha3_256);
    _ = c.EVP_DigestUpdate(context, data, len);
    var sha3_256hash: [32]u8 = undefined;
    _ = c.EVP_DigestFinal(context, &sha3_256hash, hash_length);

    // SM3
    _ = c.EVP_DigestInit(context, sm3);
    _ = c.EVP_DigestUpdate(context, data, len);
    var sm3hash: [32]u8 = undefined;
    _ = c.EVP_DigestFinal(context, &sm3hash, hash_length);

    try stdout.print("Hashing with Zig and OpenSSL:\n", .{});
    try stdout.print("Data:\t\t{s}\n\n", .{data});
    try stdout.print("MD5:\t\t{x}\n", .{md5hash});
    try stdout.print("SHA1:\t\t{x}\n", .{sha1hash});
    try stdout.print("SHA256:\t\t{x}\n", .{sha256hash});
    try stdout.print("SHA512:\t\t{x}\n", .{sha512hash});
    try stdout.print("Blake2bs256:\t{x}\n", .{blake2s256hash});
    try stdout.print("SHA3-256:\t{x}\n", .{sha3_256hash});
    try stdout.print("SM3:\t\t{x}\n", .{sm3hash});
    try stdout.flush();
}

在 Microsoft Windows 上,我们使用以下命令将其编译为可执行文件 [ 这里]:

> zig build-exe zig_openssl_hash.zig -I C:\home\openssl\include\
     -lc libcrypto.lib -target x86_64-windows

然后我们可以运行文件 zig_openssl_hash.zig.exe。 一个示例运行是 [ 这里]:

Hashing with Zig and OpenSSL:
Data:           Hello1

MD5:            7a6d1b13498fb5b3085b2fd887933575
SHA1:           dbce705929c7dc1924ea1173f37652bb00f96d6d
SHA256:         948edbe7ede5aa7423476ae29dcd7d61e7711a071aea0d83698377effa896525
SHA512:         6a68902da1f60f0f96fb1693bce159f6bc531eb88eecef3a159cec522ae451b84221fbdf84aea61f9643f8909290e0ed7bbf392476d3a888be580d44e15d2f0e
Blake2bs256:    81792af2c1ea2db1994eb035068e1e41b24879e6249f8705a8f769c84bd11e1c
SHA3-256:       cd9ad32f1dc088ab01441b3e85edee76a97009214249614607e602b19fd0508d

是不是很精彩? Zig 的强大之处在于与 OpenSSL 集成。 这是演示:

https://asecuritysite.com/zig/zig_openssl_hash

  • 原文链接: medium.com/asecuritysite...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
asecuritysite
asecuritysite
江湖只有他的大名,没有他的介绍。