kcrypt–windows内核加密算法库 | 宜武汇-ag真人国际厅网站

#pragma once

#include

#include

 

namespace kcrypt {

#pragma warning(disable :4996)

#define asymprink(...)do{dbgprintex(77,0,__va_args__);}while(0)

    struct keyinfo {

        puchar key;

        ulong keysize;

    };

 

     

    template

    class asymcipher {

         

    public:

         

        asymcipher(ulong keysize=512);

        ~asymcipher();

        ulong encrypt(puchar data, ulong datasize, puchar cryptdata, ulong cryptsize,puchar pubkey=nullptr,ulong pubsize=0);

        ulong decrypt(puchar data, ulong datasize, puchar cryptdata, ulong cryptsize,puchar prikey=nullptr,ulong prisize=0);

        keyinfo constexpr getprikey() { return { _prikey,_prisize}; }

        keyinfo constexpr getpubkey() { return { _pubkey ,_pubsize}; }

 

 

        asymcipher& operator=(asymcipher&) = delete;

        asymcipher& operator=(asymcipher&&) = delete;

        asymcipher(asymcipher&) = delete;

    private:

        bcrypt_alg_handle _halg;//create when open alg provider

        bcrypt_key_handle _hkey;//use for encrypt and decrypt

        puchar _prikey;

        puchar _pubkey;

        ulong _pubsize;

        ulong _prisize;

    private:

        bool rsacheck(ulong cbkeysize, ulong cbdata, boolean bencrypt);

         

    };

 

     

    template

    inline asymcipher::asymcipher(ulong keysize)

    {

        do {

            //check key size correct

            if (keysize != 512 && keysize != 1024 && keysize != 2048 && keysize != 4096) {

                asymprink("key len error!\r\n");

                break;

            }

             

 

            ntstatus status = 0;

            if (!nt_success(status = bcryptopenalgorithmprovider(&_halg,

                algorithm::getalgorithmname(), 0, 0))) {

                asymprink("failed to open alg provider! errcode->x\r\n",status);

                break;

            }

 

            //generate key pair and must call bcryptfinalizekeypair

            if (!nt_success(status = bcryptgeneratekeypair(_halg, &_hkey, keysize, 0))) {

                asymprink("failed to generate key pair! errcode->08%x\r\n", status);

                break;

            }

 

            //if call bcryptfinalizekeypair we can not call bcryptsetproperty anymore

            if (!nt_success(status = bcryptfinalizekeypair(_hkey, 0))) {

                asymprink("failed to finalize key pair! errcode->x\r\n", status);

                break;

            }

 

            //get public key and private key size

            if (!nt_success(status = bcryptexportkey(_hkey, 0, bcrypt_rsapublic_blob, 0, 0, &_pubsize, 0))) {

 

                asymprink("failed to get pub key size! errcode->x\r\n", status);

                break;

            }

            if (!nt_success(status = bcryptexportkey(_hkey, 0, bcrypt_rsaprivate_blob, 0, 0, &_prisize, 0))) {

 

                asymprink("failed to get private key size! errcode->x\r\n", status);

                break;

            }

            _pubkey = (puchar)exallocatepoolwithtag(nonpagedpool, _pubsize, 'asym');

            _prikey= (puchar)exallocatepoolwithtag(nonpagedpool, _prisize, 'asym');

            if (!_prikey || !_pubkey) {

                asymprink("failed to alloc mem for key! errcode->x\r\n", status);

                break;

            }

            //get public and private key

            if (!nt_success(status = bcryptexportkey(_hkey, 0, bcrypt_rsapublic_blob, _pubkey, _pubsize, &_pubsize, 0))) {

 

                asymprink("failed to get pub key! errcode->x\r\n", status);

                break;

            }

            if (!nt_success(status = bcryptexportkey(_hkey, 0, bcrypt_rsaprivate_blob, _prikey, _prisize, &_prisize, 0))) {

 

                asymprink("failed to get private key! errcode->x\r\n", status);

                break;

            }

 

            return;

 

        } while (0);

 

        //fault or err

        if (_hkey) {

 

            bcryptdestroykey(_hkey);

            _hkey = 0;

        }

        if (_halg) {

            bcryptclosealgorithmprovider(_halg,0);

            _halg = 0;

        }

        if (_prikey) {

            exfreepool(_prikey);

            _prikey = 0;

        }

        if (_pubkey) {

            exfreepool(_pubkey);

            _pubkey = 0;

 

        }

    }

 

    template

    inline asymcipher::~asymcipher()

    {

        if (_hkey) {

 

            bcryptdestroykey(_hkey);

            _hkey = 0;

        }

        if (_halg) {

            bcryptclosealgorithmprovider(_halg,0);

            _halg = 0;

        }

        if (_prikey) {

            exfreepool(_prikey);

            _prikey = 0;

        }

        if (_pubkey) {

            exfreepool(_pubkey);

            _pubkey = 0;

 

        }

 

    }

 

    //if arg5 isn't nullptr means that we need to import a new key handle to encrypt

    template

    inline ulong asymcipher::encrypt(puchar data, ulong datasize, puchar cryptdata, ulong cryptsize, puchar pubkey,ulong pubsize)

    {

        if (!_hkey) return 0;

        if (!rsacheck(pubsize ? pubsize :_pubsize, datasize, true)) {

            asymprink("key size or data size err!\r\n");

            return 0;

        }

        ulong result=0;

        ntstatus status = 0;

        if (pubkey == nullptr) {

            //using pkcs1 padding and defualt public key

            if (!nt_success(status = bcryptencrypt(_hkey, data, datasize, 0, 0, 0, cryptdata,

                cryptsize, &result, bcrypt_pad_pkcs1))) {

                asymprink("failed to encrypt! errcode->%x\r\n", status);

                return 0;

            }

            else return result;

 

        }

        else {

            //we need open new halg and create new key handle(public key)

            bcrypt_alg_handle halg = nullptr;

            bcrypt_key_handle hkey = nullptr;

            do {

                if (!nt_success(status = bcryptopenalgorithmprovider(&halg,

                    algorithm::getalgorithmname(), 0, 0))) {

                    asymprink("failed to open provider errcode->x\r\n", status);

                    break;

                }

 

                __debugbreak();

                //import key handle

                if (!nt_success(status = bcryptimportkeypair(halg

                    , nullptr, bcrypt_rsapublic_blob

                    , &hkey, pubkey, pubsize

                    , bcrypt_no_key_validation))) {

                    asymprink("failed to get key handle errcode->%x\r\n", status);

                    break;

                }

                 

                //using pkcs1 padding and defualt public key

                if (!nt_success(status = bcryptencrypt(hkey, data, datasize, 0, 0, 0, cryptdata,

                    cryptsize, &result, bcrypt_pad_pkcs1))) {

                    asymprink("failed to encrypt! errcode->%x\r\n", status);

                    result = 0;

                    break;

                }

                else break;

                 

            } while (0);

             

            if (hkey) {

                bcryptdestroykey(hkey);

            }

            if (halg) {

                bcryptclosealgorithmprovider(halg, 0);

            }

            return result;

 

        }

 

    }

 

    //if arg5 isn't nullptr means that we need to import a new key handle to decrypt

    template

    inline ulong asymcipher::decrypt(puchar data, ulong datasize, puchar cryptdata, ulong cryptsize, puchar prikey,ulong prisize)

    {

        if (!_hkey) return 0;

        if (!rsacheck(prisize ? prisize :_prisize, datasize, false)) {

            asymprink("key size or data size err!\r\n");

            return 0;

        }

        ulong result = 0;

        ntstatus status = 0;

        //using pkcs1 padding

        if (prikey == nullptr) {

            if (!nt_success(status = bcryptdecrypt(_hkey, cryptdata, cryptsize, 0, 0, 0, data,

                datasize, &result, bcrypt_pad_pkcs1))) {

                asymprink("failed to decrypt! errcode->%x\r\n", status);

                return 0;

            }

            else return result;

 

        }

        else {

 

            //we need open new halg and create new key handle(public key)

            bcrypt_alg_handle halg = nullptr;

            bcrypt_key_handle hkey = nullptr;

            do {

                if (!nt_success(status = bcryptopenalgorithmprovider(&halg,

                    algorithm::getalgorithmname(), 0, 0))) {

                    asymprink("failed to open provider errcode->x\r\n", status);

                    break;

                }

 

                //import key handle

                if (!nt_success(status = bcryptimportkeypair(halg

                    , nullptr, bcrypt_rsaprivate_blob

                    , &hkey, prikey, prisize

                    , bcrypt_no_key_validation))) {

                    asymprink("failed to get key handle errcode->x\r\n", status);

                    break;

                }

 

                //using pkcs1 padding and defualt public key

                if (!nt_success(status = bcryptdecrypt(hkey, cryptdata, cryptsize, 0, 0, 0, data,

                    datasize, &result, bcrypt_pad_pkcs1))) {

                    asymprink("failed to decrypt! errcode->%x\r\n", status);

                    result = 0;

                    break;

                }

                else break;

 

            } while (0);

 

            if (hkey) {

                bcryptdestroykey(hkey);

            }

            if (halg) {

                bcryptclosealgorithmprovider(halg, 0);

            }

            return result;

 

        }

 

    }

 

 

    /*

    the length of the content that can be encrypted

    depends on the bis size of the key.

    for 512bit key:

    public key length: 91, private key: 155

    for 1024bit:

    public key: 155, private key: 283

    for 2048bit:

    public key: 283, private key: 539

    for 4096bit:

    public key: 539, private key: 1051

    */

    template

    inline bool asymcipher::rsacheck(ulong cbkeysize, ulong cbdata, boolean bencrypt)

    {

        if (bencrypt)

        {

            switch (cbkeysize)

            {

            case 91: // 512bit

                if (cbdata > 64)

                    return false;

                break;

            case 155: // 1024bit

                if (cbdata > 128)

                    return false;

                break;

            case 283: // 2048bit

                if (cbdata > 256)

                    return false;

                break;

            case 539: // 4096bit

                if (cbdata > 512)

                    return false;

                break;

                return false;

                break;

            }

            /*if (cbkeysize - cbdata > 27)

                return true;

            else

                return false;*/

            return true;

        }

        else

        {

            switch (cbkeysize)

            {

            case 155: // 512bit

            case 283: // 1024bit

            case 539: // 2048bit

            case 1051: // 4096bit

                return true;

                break;

                return false;

                break;

            }

        }

    }

 

 

     

    class rsa {

    public:

        static constexpr lpcwstr getalgorithmname() {

            return bcrypt_rsa_algorithm;

        }

 

    };

 

    class dsa {

    public:

        static constexpr lpcwstr getalgorithmname() {

            return bcrypt_dsa_algorithm;

        }

 

    };

 

    using rsacreator = asymcipher;

#pragma warning(default :4996)

原文链接:https://bbs.kanxue.com/thread-278284.htm

网络摘文,本文作者:15h,如若转载,请注明出处:https://www.15cov.cn/2023/08/27/kcrypt-windows内核加密算法库/

发表评论

邮箱地址不会被公开。 必填项已用*标注

网站地图