python代码

import hashlib
import binascii


def scrypt_kdf_python(password: str, salt: str):
    """
    等效于 Rust 版的 scrypt_kdf:
    参数: N=32768 (2^15), r=8, p=1, dklen=32
    """
    # 1. 将字符串转换为字节数组
    password_bytes = password.encode("utf-8")
    salt_bytes = salt.encode("utf-8")

    # 2. 内部计算 (对应 scrypt_derive_key_internal)
    # n=32768, r=8, p=1, dklen=32
    key_bytes = hashlib.scrypt(
        password=password_bytes,
        salt=salt_bytes,
        n=32768,
        r=8,
        p=1,
        dklen=32,
        maxmem=64 * 1024 * 1024,  # 这里的单位是字节
    )

    # 3. 转换为十六进制字符串 (对应 hex::encode)
    return binascii.hexlify(key_bytes).decode("utf-8")


if __name__ == "__main__":
    pwd = "secret123"
    slt = "somesalt"

    result = scrypt_kdf_python(pwd, slt)
    assert result == "ab987e2ef8501600c5413c7ae1eb0bed219dff784a1e4bf56017f8ea0261d780"
    print(f"Result: {result}")
    # 64位十六进制字符
    print(f"Length: {len(result)}")

Rust代码

1. Cargo.toml

[package]
name = "kdf_scrypt"
version = "0.1.0"
edition = "2024"

[lib]
crate-type = ["cdylib"]
name = "scrypt"

[dependencies]
hex = "0.4.3"
scrypt = "0.11.0"

2. lib.rs

use hex;
use scrypt::Params;
use std::ffi::{CStr, CString};
use std::os::raw::c_char;
use std::ptr;

#[unsafe(no_mangle)]
pub unsafe extern "C" fn scrypt_kdf(password: *const c_char, salt: *const c_char) -> *mut c_char {
    // 1. 检查指针是否为 null
    if password.is_null() || salt.is_null() {
        return ptr::null_mut();
    }
    // 2. 将 C 字符串转换为字节数组 (更健壮,不强制要求 UTF-8)
    let password_bytes = unsafe { CStr::from_ptr(password).to_bytes() };
    let salt_bytes = unsafe { CStr::from_ptr(salt).to_bytes() };
    // 3. 内部计算
    match scrypt_derive_key_internal(password_bytes, salt_bytes) {
        Ok(key_hex) => {
            // 将 Rust 字符串转换为 C 字符串并将所有权移交给 C
            match CString::new(key_hex) {
                Ok(c_string) => c_string.into_raw(),
                Err(_) => ptr::null_mut(),
            }
        }
        Err(_) => ptr::null_mut(),
    }
}

/// 必须提供此函数供其他语言调用,以释放 scrypt_kdf 返回的内存
#[unsafe(no_mangle)]
pub unsafe extern "C" fn free_string(s: *mut c_char) {
    if s.is_null() {
        return;
    }
    unsafe {
        let _ = CString::from_raw(s);
    } // 变量在此处离开作用域,内存被释放
}

// 内部逻辑优化
fn scrypt_derive_key_internal(
    password: &[u8],
    salt: &[u8],
) -> Result<String, Box<dyn std::error::Error>> {
    // 配置 Scrypt 参数: N=32768, r=8, p=1
    let params = Params::new(15, 8, 1, 32)?;

    let mut output = vec![0u8; 32];
    scrypt::scrypt(password, salt, &params, &mut output)?;

    Ok(hex::encode(output))
}

3. 编译成32位dll

cargo build --release --target i686-pc-windows-msvc

aardio代码

import console;

::ScryptLib = raw.loadDll("D:\rust_project\kdf_scrypt\target\i686-pc-windows-msvc\release\scrypt.dll",,"cdecl"); 

var scrypt_kdf = ::ScryptLib.api("scrypt_kdf", "pointer(string password, string salt)");
var free_string = ::ScryptLib.api("free_string", "void(pointer)");

// 调用
var ptr = scrypt_kdf("secret123", "somesalt");
if(ptr && ptr !== 0){
    var kdf_result = raw.str(ptr);
    console.log("KDF 结果:", kdf_result);

    // 释放内存
    free_string(ptr);
}
console.pause();

阅读量: 120 | 标签: 暂无标签

添加新评论