netcore调用(DllImport)C++库的接口(Linux和Windows)

目录

一.前言

二.netcore调用

1.windows库引用dll文件

2.linux库引用so文件

3.C++接口所需结构体

4.实现帮助类/返回结果类


一.前言

C++提供了windows和linux的两种库,netcore调用并实现.

二.netcore调用

1.windows库引用dll文件

public static class VVSecurity_win32
{
    private const string dllName = "Lib/vvsec_win32/VVSecurity.dll";
    [DllImport(dllName, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
    public static extern int VVSec_Initlize(IntPtr pDevice, string pUserPin);
    [DllImport(dllName, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
    public static extern int VVSec_SM4EncryptData(DEVICE_HANDLE pDevice, PKI_DATA plaintext, ref PKI_DATA ciphertext);
    [DllImport(dllName, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
    public static extern int VVSec_SM4DecryptData(DEVICE_HANDLE pDevice, PKI_DATA ciphertext, ref PKI_DATA plaintext);
    [DllImport(dllName, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
    public static extern int VVSec_Finalize(DEVICE_HANDLE pDevice);
}

2.linux库引用so文件

public static class VVSecurity_centos64
{
    private const string dllName = "Lib/vvsec_centosx64/VVSecurity.so";
    [DllImport(dllName, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
    public static extern int VVSec_Initlize(IntPtr pDevice, string pUserPin);
    [DllImport(dllName, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
    public static extern int VVSec_SM4EncryptData(DEVICE_HANDLE pDevice, PKI_DATA plaintext, ref PKI_DATA ciphertext);
    [DllImport(dllName, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
    public static extern int VVSec_SM4DecryptData(DEVICE_HANDLE pDevice, PKI_DATA ciphertext, ref PKI_DATA plaintext);
    [DllImport(dllName, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
    public static extern int VVSec_Finalize(DEVICE_HANDLE pDevice);
}

3.C++接口所需结构体

public struct DEVICE_HANDLE
{
    public uint hdev { get; set; }
    public uint hcont { get; set; }
    public uint happ { get; set; }
}

/// <summary>
/// 加解密结构体:用句柄接收byte[]返回值
/// </summary>
public struct PKI_DATA
{
    /// <summary>
    /// value的长度,以16位单位增长.加密后的密文存储空间需要计算.
    /// </summary>
    public int size { get; set; }
    /// <summary>
    /// 值:byte[]句柄
    /// </summary>
    public IntPtr value { get; set; }
}

4.实现帮助类/返回结果类

public static class VVSecurityHelper
{
    public static bool IsSuccessVVSecInit { get { return _issSuccessVVSecInit; } }
    private static bool _issSuccessVVSecInit = false;
    private static object _lockEncrypt = new object();//加密锁
    private static object _lockDecrypt = new object();//解密锁

    #region 处理后的加解密
    private static DEVICE_HANDLE _deviceHandle = new DEVICE_HANDLE();

    public static VVSecResult Init(string pUserPin = null)
    {
        try
        {
            DEVICE_HANDLE dh = new DEVICE_HANDLE();
            GCHandle initlizeHandle = GCHandle.Alloc(dh, GCHandleType.Pinned);
            var pdevice = Marshal.AllocHGlobal(12);
            Marshal.StructureToPtr(dh, pdevice, false);
            int code = 0;
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
            {
                #region 设置动态库路径
                StreamWriter sw = new StreamWriter("aavs.sh", false, Encoding.ASCII);
                string dirPath = Path.Combine(Directory.GetCurrentDirectory(), "Lib/vvsec_centosx64").Trim('/').Replace("/", "\\/");
                sw.WriteLine($"sed -i '/{dirPath}/d' /etc/ld.so.conf");//删除配置项
                sw.WriteLine($"echo '{Directory.GetCurrentDirectory()}/Lib/vvsec_centosx64'>>/etc/ld.so.conf");//增加配置项
                sw.WriteLine("ldconfig");
                sw.Close();

                Process process = new Process();
                process.StartInfo.FileName = "sh";
                process.StartInfo.Arguments = "aavs.sh";
                process.Start();
                process.WaitForExit();
                process.Close();
                #endregion
                code = VVSecurity_centos64.VVSec_Initlize(pdevice, pUserPin);
            }
            else
            {
                code = VVSecurity_win32.VVSec_Initlize(pdevice, pUserPin);
            }
            Console.WriteLine($"安全加密.初始化:状态码{code}");
            _issSuccessVVSecInit = code == 0;
            _deviceHandle = Marshal.PtrToStructure<DEVICE_HANDLE>(pdevice);
            initlizeHandle.Free();
            return new VVSecResult { code = code };
        }
        catch (Exception ex)
        {
            Console.WriteLine("安全加密初始化异常:" + ex.ToString());
            return new VVSecResult { code = -2, msessage = ex.ToString() };
        }
    }

    public static VVSecResult Encrypt(string plaintextStr)
    {
        //初始化未成功,原文返回
        if (!_issSuccessVVSecInit) return new VVSecResult { code = -1, text = plaintextStr };
        //空内容
        if (string.IsNullOrEmpty(plaintextStr)) return new VVSecResult { code = 0, text = "" };
        lock (_lockEncrypt)
        {
            //明文 
            byte[] plaintextBt = Encoding.UTF8.GetBytes(plaintextStr);
            var plaintextGCH = GCHandle.Alloc(plaintextBt, GCHandleType.Pinned);
            PKI_DATA plaintextData = new PKI_DATA() { size = plaintextBt.Length, value = plaintextGCH.AddrOfPinnedObject() };
            plaintextGCH.Free();
            //密文
            var ciphertextLen = (plaintextBt.Length / 16 + 1) * 16;//以16为单位增长
            byte[] ciphertextBt = new byte[ciphertextLen];
            var ciphertextGCH = GCHandle.Alloc(ciphertextBt, GCHandleType.Pinned);
            PKI_DATA ciphertextData = new PKI_DATA() { size = ciphertextLen, value = ciphertextGCH.AddrOfPinnedObject() };
            int code = 0;
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
            {
                code = VVSecurity_centos64.VVSec_SM4EncryptData(_deviceHandle, plaintextData, ref ciphertextData);
            }
            else
            {
                code = VVSecurity_win32.VVSec_SM4EncryptData(_deviceHandle, plaintextData, ref ciphertextData);
            }
            var byteArr = (byte[])ciphertextGCH.Target;//密文返回值
            var plaintextResult = code == 0 ? Convert.ToBase64String(byteArr) : "";
            ciphertextGCH.Free();
            var result = new VVSecResult() { code = code, text = plaintextResult };
            return result;
        }
    }

    public static VVSecResult Decrypt(string ciphertextBase64)
    {
        //初始化未成功,原文返回
        if (!_issSuccessVVSecInit) return new VVSecResult { code = -1, text = ciphertextBase64 };
        //空内容
        if (string.IsNullOrEmpty(ciphertextBase64)) return new VVSecResult { code = 0, text = "" };
        lock (_lockDecrypt)
        {
            byte[] ciphertextBt = null;
            try
            {
                ciphertextBt = Convert.FromBase64String(ciphertextBase64);
            }
            catch (Exception)
            {
                return new VVSecResult { code = -3, text = "" };//要解密的字符串不是base64内容
            }
            //空密文直接返回
            if (ciphertextBt == null || ciphertextBt.Length == 0) return new VVSecResult { code = 0, text = "" };
            //密文
            var ciphertextGCH = GCHandle.Alloc(ciphertextBt, GCHandleType.Pinned);
            PKI_DATA ciphertextData = new PKI_DATA() { size = ciphertextBt.Length, value = ciphertextGCH.AddrOfPinnedObject() };
            ciphertextGCH.Free();
            //明文
            byte[] plaintextBt = new byte[ciphertextBt.Length];
            var plaintextGCH = GCHandle.Alloc(plaintextBt, GCHandleType.Pinned);
            PKI_DATA plaintextData = new PKI_DATA() { size = plaintextBt.Length, value = plaintextGCH.AddrOfPinnedObject() };
            int code = 0;
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
            {
                code = VVSecurity_centos64.VVSec_SM4DecryptData(_deviceHandle, ciphertextData, ref plaintextData);
            }
            else
            {
                code = VVSecurity_win32.VVSec_SM4DecryptData(_deviceHandle, ciphertextData, ref plaintextData);
            }
            var byteArr = (byte[])plaintextGCH.Target;//明文byte数组
            plaintextGCH.Free();
            var text = Encoding.UTF8.GetString(byteArr).Replace("\0", "");//去掉明文中的空位
            var result = new VVSecResult() { code = code, text = text };
            return result;
        }
    }
    #endregion
}
public class VVSecResult
{
    /// <summary>
    /// 状态码:0成功,其他失败
    /// </summary>
    public int code { get; set; }
    /// <summary>
    /// 加密后的base64密文 / 解密后的明文
    /// </summary>
    public string text { get; set; }
    public string msessage { get; set; }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值