首页 > 编程语言 >C#调用libsodium加密库

C#调用libsodium加密库

时间:2023-10-16 10:12:13浏览次数:36  
标签:libsodium 加密 ulong aad C# unsafe int byte public

C#自带加密库在System.Security.Cryptography中,但是其自带的加密功能比较简单,只有一些基础的加密功能,一些高级加密方法如Aead加密,在最新版本中也只支持AesGcm96。

而基于C#的比较全面的第三方加密库如BouncyCastle.NET功能虽然比较全面,但是执行效率比较差,一般比用C语言实现的加密库要慢2-3倍。

基于C语言的libsodium是功能强大而且执行效率也很高的加密库,其内部API组织比较合理,使用起来非常简单,但是不支持C#直接调用,不过由于其使用的C函数封装,而且函数参数都是比较简单的原始数据类型,所以通过C#的Native Invoke,能比较方便的调用这些函数,只需要注意数据类型的转换和启用编译器的不安全代码(Unsafe)支持即可。

下面通过哈希计算和Aead加密,演示libsodium的调用方法。

Sha256哈希计算:

        [DllImport(dll, CallingConvention = CallingConvention.Cdecl)]
        static unsafe extern int crypto_hash_sha256
            (
            byte* dst,
            byte* src, long srcLen
            );

        public static unsafe void sha256(byte[] src, byte[] dst)
        {
            fixed (byte* srcPtr = src,
                dstPtr = dst)
            {
                crypto_hash_sha256
                    (
                    dstPtr,
                    srcPtr, src.Length
                    );
            }
        }

        public static unsafe byte[] sha256(byte[] src)
        {
            byte[] dst = new byte[32];
            sha256(src, dst);
            return dst;
        }

Argon2密码哈希:

        [DllImport(dll, CallingConvention = CallingConvention.Cdecl)]
        public static unsafe extern int crypto_pwhash_argon2id(
            byte* key, long keyLen,
            byte* pwd, long pwdLen,
            byte* salt,
            long cpu, int mem,
            int alg);

Aead加密模式的chacha20poly1305和gcm:

        [DllImport(Sodium.dll, CallingConvention = CallingConvention.Cdecl)]
        public static unsafe extern int
            crypto_aead_chacha20poly1305_ietf_encrypt(
            byte* cipher,
            out ulong cipherLen,
            byte* data,
            ulong dataLen,
            byte* aad,
            ulong aadLen,
            byte* nsec,
            byte* nonce,
            byte* key);

        [DllImport(Sodium.dll, CallingConvention = CallingConvention.Cdecl)]
        public static unsafe extern int
            crypto_aead_chacha20poly1305_ietf_decrypt(
            byte* data,
            out ulong dataLen,
            byte* nsec,
            byte* cipher,
            ulong cipherLen,
            byte* aad,
            ulong aadLen,
            byte* nonce,
            byte* key);

        [DllImport(Sodium.dll, CallingConvention = CallingConvention.Cdecl)]
        public static unsafe extern int
            crypto_aead_aes256gcm_encrypt(
            byte* cipher,
            out ulong cipherLen,
            byte* data,
            ulong dataLen,
            byte* aad,
            ulong aadLen,
            byte* nsec,
            byte* nonce,
            byte* key);

        [DllImport(Sodium.dll, CallingConvention = CallingConvention.Cdecl)]
        public static unsafe extern int
            crypto_aead_aes256gcm_decrypt(
            byte* data,
            out ulong dataLen,
            byte* nsec,
            byte* cipher,
            ulong cipherLen,
            byte* aad,
            ulong aadLen,
            byte* nonce,
            byte* key);

Argon2id类的封装:

    public class Argon2id : KeyGen
    {
        public Argon2id() => Sodium.checkLib();

        public const int SaltSize = 16;

        public byte[] salt;
        public long cpu = 32;
        public int mem = 64.mb();

        public override byte[] genKey(byte[] pwd, int keySize)
            => Sodium.argon2id(pwd, salt, cpu, mem, keySize);
    }

Aead模式的类的封装:

    public abstract class SodiumAeadCrypt : AeadCrypt
    {
        public SodiumAeadCrypt() => Sodium.checkLib();

        public override unsafe void encrypt(byte[] data, int dataOff, int dataLen,
                            byte[] nonce,
                            byte[] cipher, int cipherOff = 0,
                            byte[] aad = null)
        {
            fixed (byte* cipherPtr = cipher)
            fixed (byte* dataPtr = data)
            fixed (byte* noncePtr = nonce)
            fixed (byte* keyPtr = Key)
            fixed (byte* aadPtr = aad)
            {
                encFunc
                    (
                    cipherPtr + cipherOff, out var cipherLen,
                    dataPtr + dataOff, (ulong)dataLen,
                    aadPtr, (ulong)(aad?.Length ?? 0),
                    null,
                    noncePtr,
                    keyPtr
                    );
            }
        }

        public override unsafe bool decrypt(byte[] cipher, int cipherOff, int cipherLen,
                                    byte[] nonce,
                                    byte[] data, int dataOff = 0,
                                    byte[] aad = null)
        {
            fixed (byte* cipherPtr = cipher)
            fixed (byte* dataPtr = data)
            fixed (byte* noncePtr = nonce)
            fixed (byte* keyPtr = Key)
            fixed (byte* aadPtr = aad)
            {
                return decFunc
                    (
                    dataPtr + dataOff, out var dataLen,
                    null,
                    cipherPtr + cipherOff, (ulong)cipherLen,
                    aadPtr, (ulong)(aad?.Length ?? 0),
                    noncePtr,
                    keyPtr
                    ) == 0;
            }
        }

        protected abstract DecryptFunc decFunc { get; }
        protected abstract EncryptFunc encFunc { get; }

        protected unsafe delegate int EncryptFunc(
            byte* cipher,
            out ulong cipherLen,
            byte* data,
            ulong dataLen,
            byte* aad,
            ulong aadLen,
            byte* nsec,
            byte* nonce,
            byte* key);

        protected unsafe delegate int DecryptFunc(
            byte* data,
            out ulong dataLen,
            byte* nsec,
            byte* cipher,
            ulong cipherLen,
            byte* aad,
            ulong aadLen,
            byte* nonce,
            byte* key);
    }

其他libsodium的API都可以通过类似的方法进行调用。

 

Github:

https://github.com/bsmith-zhao/vfs/tree/main/util/crypt/sodium

标签:libsodium,加密,ulong,aad,C#,unsafe,int,byte,public
From: https://www.cnblogs.com/bsmith/p/17766763.html

相关文章

  • java和c#里的TOTP统一算法
    基础说明本文根据RFC4226和RFC6238文档,详细的介绍HOTP和TOTP算法的原理和实现。两步验证已经被广泛应用于各种互联网应用当中,用来提供安全性。对于如何使用两步验证,大家并不陌生,无非是开启两步验证,然后出现一个二维码,使用支持两步验证的移动应用比如GoogleAuthenticat......
  • 【转】第一篇-linux中socket通信
     转,原文:https://zhuanlan.zhihu.com/p/628583834---------------- 客户端和服务端是如何通信的在linux中客户端和服务端通信的流程如图所示:流程分析:服务器端先初始化Socket,然后与端口绑定(bind),对端口进行监听(listen),调用accept阻塞,等待客户端连接。在这时如果有个客户......
  • 什么???CSS也能原子化!
    1.什么是原子化CSS?AtomicCSSistheapproachtoCSSarchitecturethatfavorssmall,single-purposeclasseswithnamesbasedonvisualfunction.Let’sDefineExactlyWhatAtomicCSSis上文的意思翻译过来就是原子化CSS是一种CSS的架构方法,倾向于使用用途单一且......
  • Programming abstractions in C阅读笔记:p179-p180
    《ProgrammingAbstractionsInC》学习第60天,p179-p180总结。一、技术总结1.palindrome(回文)(1)包含单个字符的字符串(如"a"),或者空字符串(如"")也是回文。(2)示例:“level”、"noon"。2.predicatefunction(1)predicate的意思pre-("forth")+*deik-("show"),“t......
  • 安装centos可以联网
    一问题VMvare中安装了centOS,连不了外网,解决办法如下:二解决1.打开文件cat/etc/sysconfig/network-scripts/ifcfg-ens33vi/etc/sysconfig/network-scripts/ifcfg-ens33 2.修改最后一行,使网卡随操作系统启动 3.重新加载网卡systemctlrestartnetwork ......
  • C#固定时间间隔触发的计数器
    在运行需要很长时间完成的任务时,一般需要定期展示当前处理进度,比如批量文件复制时,显示复制的文件数和总传输字节数,这时候就需要用计数器对处理任务的完成度进行统计,并以一定时间间隔(如500ms)显示当前统计结果。实现上述功能需要使用一些内部变量来保存当前进度:longlast......
  • web前端html+css页面内容的六种隐藏方式
    一、使用透明度语法:opacity:0注意:元素消失,但是还会占据空间,只是视觉看不出来<style>.box{width:100px;height:100px;background-color:aquamarine;opacity:0;}</style><divclass="box"></div> 二、使用display语法:display:none注意:元素消失,不会占据空间<style......
  • 题解 AcWing 1272. 与众不同
    题目描述定义完美序列:若一个序列内没有重复的数,称这个数列为完美数列。每次给定一个区间\([l,r]\),求这个区间内最长的完美序列长度。具体思路设\(len_i\)表示从\(i\)出发往右的最长完美序列长度。我们定义一个指针\(st\),表示当前枚举的区间左端点,同时定义多一个指针\(......
  • 【RocketMQ】RocketMQ 5.0新特性(三)- Controller模式
    在RocketMQ5.0以前,有两种集群部署模式,分别为主从模式(Master-Slave模式)和Dledger模式。主从模式主从模式中分为Master和Slave两个角色,集群中可以有多个Master节点,一个Master节点可以有多个Slave节点。Master节点负责接收生产者发送的写入请求,将消息写入CommitLog文件,Slave节点会......
  • PAT_A1070 Mooncake
    MooncakeisaChinesebakeryproducttraditionallyeatenduringtheMid-AutumnFestival.Manytypesoffillingsandcrustscanbefoundintraditionalmooncakesaccordingtotheregion'sculture.Nowgiventheinventoryamountsandthepricesofall......