{"id":13636274,"url":"https://github.com/spacewander/lua-resty-rsa","last_synced_at":"2025-04-06T21:16:40.222Z","repository":{"id":24478899,"uuid":"27882984","full_name":"spacewander/lua-resty-rsa","owner":"spacewander","description":"RSA encrypt/decrypt \u0026 sign/verify for OpenResty/LuaJIT","archived":false,"fork":false,"pushed_at":"2022-05-26T05:29:59.000Z","size":142,"stargazers_count":264,"open_issues_count":10,"forks_count":101,"subscribers_count":21,"default_branch":"master","last_synced_at":"2024-08-17T14:02:30.320Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Lua","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/spacewander.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-12-11T17:24:33.000Z","updated_at":"2024-08-12T07:13:44.000Z","dependencies_parsed_at":"2022-08-06T02:01:01.272Z","dependency_job_id":null,"html_url":"https://github.com/spacewander/lua-resty-rsa","commit_stats":null,"previous_names":["doujiang24/lua-resty-rsa"],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spacewander%2Flua-resty-rsa","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spacewander%2Flua-resty-rsa/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spacewander%2Flua-resty-rsa/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spacewander%2Flua-resty-rsa/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/spacewander","download_url":"https://codeload.github.com/spacewander/lua-resty-rsa/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247550693,"owners_count":20956987,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-02T00:00:59.374Z","updated_at":"2025-04-06T21:16:40.206Z","avatar_url":"https://github.com/spacewander.png","language":"Lua","funding_links":[],"categories":["Libraries"],"sub_categories":[],"readme":"Name\n=============\n\nlua-resty-rsa - RSA functions for OpenResty\n\nStatus\n======\n\nThis library is considered production ready.\n\nBuild status: ![https://github.com/spacewander/lua-resty-rsa/workflows/build/badge.svg?branch=master](https://github.com/spacewander/lua-resty-rsa/actions/workflows/ci.yml/badge.svg?branch=master)\n\n\nDescription\n===========\n\nThis library requires an nginx build with OpenSSL,\nthe [ngx_lua module](https://github.com/openresty/lua-nginx-module), and [LuaJIT](http://luajit.org/luajit.html).\n\n\nSynopsis\n========\n\n```lua\n    # nginx.conf:\n\n    lua_package_path \"/path/to/lua-resty-rsa/lib/?.lua;;\";\n\n    server {\n        location = /test {\n            content_by_lua_file conf/test.lua;\n        }\n    }\n\n    -- conf/test.lua:\n\n    local resty_rsa = require \"resty.rsa\"\n    local rsa_public_key, rsa_priv_key, err = resty_rsa:generate_rsa_keys(2048)\n    if not rsa_public_key then\n        ngx.say('generate rsa keys err: ', err)\n    end\n\n    ngx.say(rsa_public_key)\n    --[[\n    -----BEGIN RSA PUBLIC KEY-----\n    MIIBCgKCAQEAuw4T755fepEyXTM66pzf6nv8NtnukQTMGnhmBFIFHp/P2vEpxjXU\n    BBDUpzKkVFR3wuK9O1FNmRDAGNGYC0N/9cZNdhykA1NixJfKQzncN31VJTmNqJNZ\n    W0x7H9ZGoh2aE0zCCZpRlC1Rf5rL0SVlBoQkn/n9LnYFwyLLIK5/d/y/NZVL6Z6L\n    cyvga0zRajamLIjY0Dy/8YIwVV6kaSsHeRv2cOB03eam6gbhLGIz/l8wuJhIn1rO\n    yJLQ36IOJymbbNmcC7+2hEQJP40qLvH7hZ1LaAkgQUHjfi8RvH2T1Jmce7XGPxCo\n    Ed0yfeFz+pL1KeSWNey6cL3N5hJZE8EntQIDAQAB\n    -----END RSA PUBLIC KEY-----\n    ]]--\n\n    ngx.say(rsa_priv_key)\n    --[[\n    -----BEGIN RSA PRIVATE KEY-----\n    MIIEpAIBAAKCAQEAuw4T755fepEyXTM66pzf6nv8NtnukQTMGnhmBFIFHp/P2vEp\n    xjXUBBDUpzKkVFR3wuK9O1FNmRDAGNGYC0N/9cZNdhykA1NixJfKQzncN31VJTmN\n    qJNZW0x7H9ZGoh2aE0zCCZpRlC1Rf5rL0SVlBoQkn/n9LnYFwyLLIK5/d/y/NZVL\n    6Z6Lcyvga0zRajamLIjY0Dy/8YIwVV6kaSsHeRv2cOB03eam6gbhLGIz/l8wuJhI\n    n1rOyJLQ36IOJymbbNmcC7+2hEQJP40qLvH7hZ1LaAkgQUHjfi8RvH2T1Jmce7XG\n    PxCoEd0yfeFz+pL1KeSWNey6cL3N5hJZE8EntQIDAQABAoIBAGim1ayIFK8EMQNH\n    uDyui/Aqcc9WWky0PGTK23irUsXxb1708gQ89WNY70Cj6qBrqZ1VMb3QHPP4FSFN\n    kh0rJJoi2g+ssm5R5r5KlhTKeFRrQInVC1Y3KhUUUwZa4aWtnhgSJ7Urq1yVhjU4\n    K7PVkhH1OHBwcp/d1Bd6jd65AgPkY63P+WpcARJkClmQ1RhgoRwThyJdpKrV4/gO\n    ha0AUGlJNRNvRwiZxP0zaI5C8RdrG96SnVpeYOcD0z/M1HVlkoYMXsXLKttwLfpK\n    88Igtm6ZJwRpfuMF5VA+9hHaYGCBdGz0B/rMp2fc+EtrOavYQGrWIWi2RL1Qk6Rt\n    BUyeTgECgYEA9anj4n/cak1MT+hbNFsL31mJXryl1eVNjEZj/iPMztpdS15CmFgj\n    Kjr9UuintjSiK7Is43nZUWWyP1XQjRhVi2uP7PRIv92QNl/YteWD6tYCInJHKe2J\n    QqYyZrElezsdayXb5DK6bi1UIYYji90g79N7x6pOR0UnQNQUXTv+Y8ECgYEAwuzl\n    6Ez4BSXIIL9NK41jfNMa73Utfl5oO1f6mHM2KbILqaFE76PSgEeXDbOKdcjCbbqC\n    KCGjwyPd+Clehg4vkYXTq1y2SQGHwfz7DilPSOxhPY9ND7lGbeNzDUK4x8xe52hd\n    MWKdgqeqCK83e5D0ihzRiMah8dbxmlfLAOZ3sPUCgYEA0dT9Czg/YqUHq7FCReQG\n    rg3iYgMsexjTNh/hxO97PqwRyBCJPWr7DlU4j5qdteobIsubv+kSEI6Ww7Ze3kWM\n    u/tyAeleQlPTnD4d8rBKD0ogpJ+L3WpBNaaToldpNmr149GAktgpmXYqSEA1GIAW\n    ZAL11UPIfOO6dYswobpevYECgYEApSosSODnCx2PbMgL8IpWMU+DNEF6sef2s8oB\n    aam9zCi0HyCqE9AhLlb61D48ZT8eF/IAFVcjttauX3dWQ4rDna/iwgHF5yhnyuS8\n    KayxJJ4+avYAmwEnfzdJpoPRpGI0TCovRQhFZI8C0Wb+QTJ7Mofmt9lvIUc64sff\n    GD0wT/0CgYASMf708dmc5Bpzcis++EgMJVb0q+ORmWzSai1NB4bf3LsNS6suWNNU\n    zj/JGtMaGvQo5vzGU4exNkhpQo8yUU5YbHlA8RCj7SYkmP78kCewEqxlx7dbcuj2\n    LAPWpiDca8StTfEphoKEVfCPHaUk0MlBHR4lCrnAkEtz23vhZKWhFw==\n    -----END RSA PRIVATE KEY-----\n    ]]--\n\n    local pub, err = resty_rsa:new({ public_key = rsa_public_key })\n    if not pub then\n        ngx.say(\"new rsa err: \", err)\n        return\n    end\n    local encrypted, err = pub:encrypt(\"hello\")\n    if not encrypted then\n        ngx.say(\"failed to encrypt: \", err)\n        return\n    end\n    ngx.say(\"encrypted length: \", #encrypted)\n\n    local priv, err = resty_rsa:new({ private_key = rsa_priv_key })\n    if not priv then\n        ngx.say(\"new rsa err: \", err)\n        return\n    end\n    local decrypted = priv:decrypt(encrypted)\n    ngx.say(decrypted == \"hello\")\n\n    local algorithm = \"SHA256\"\n    local priv, err = resty_rsa:new({ private_key = rsa_priv_key, algorithm = algorithm })\n    if not priv then\n        ngx.say(\"new rsa err: \", err)\n        return\n    end\n\n    local str = \"hello\"\n    local sig, err = priv:sign(str)\n    if not sig then\n        ngx.say(\"failed to sign:\", err)\n        return\n    end\n    ngx.say(\"sig length: \", #sig)\n\n    local pub, err = resty_rsa:new({ public_key = rsa_public_key, algorithm = algorithm })\n    if not pub then\n        ngx.say(\"new rsa err: \", err)\n        return\n    end\n    local verify, err = pub:verify(str, sig)\n    if not verify then\n        ngx.say(\"verify err: \", err)\n        return\n    end\n    ngx.say(verify)\n```\n\n\nMethods\n=======\n\nTo load this library,\n\n1. you need to specify this library's path in ngx_lua's [lua_package_path](https://github.com/openresty/lua-nginx-module#lua_package_path) directive. For example, `lua_package_path \"/path/to/lua-resty-rsa/lib/?.lua;;\";`.\n2. you use `require` to load the library into a local Lua variable:\n\n```lua\n    local rsa = require \"resty.rsa\"\n```\n\ngenerate_rsa_keys\n---\n`syntax: public_key, private_key, err = rsa:generate_rsa_keys(bits, in_pkcs8_fmt)`\n\n Generate rsa public key and private key by specifying the number of `bits`.\n The `in_pkcs8_fmt` is optional. If `in_pkcs8_fmt` is true, the generated priviate key is in PKCS#8 format and\n the public key is in PKIX format, which start with `-----BEGIN PUBLIC` or `-----BEGIN PRIVATE`.\n Otherwise the generated keys are in PKCS#1 format, which start with `-----BEGIN RSA`.\n\nnew\n---\n`syntax: obj, err = rsa:new(opts)`\n\nCreates a new rsa object instance by specifying an options table `opts`.\n\nThe options table accepts the following options:\n\n* `public_key`\nSpecifies the public rsa key.\n* `private_key`\nSpecifies the private rsa key.\n* `password`\nSpecifies the password to read rsa key.\n* `key_type`\nSpecifies the type of given key.\nBy default the type will be detected from the value of the key.\n\n| `key_type` value | meaning |\n| ------------------- | ------ |\n| rsa.KEY_TYPE.PKCS1 | The input key is in PKCS#1 format(usually starts with `-----BEGIN RSA PUBLIC`). |\n| rsa.KEY_TYPE.PKIX | The input key is in PKIX format(usually starts with `-----BEGIN PUBLIC`). |\n\n```lua\n-- creates a rsa object with PKIX format of public key\nlocal resty_rsa = require \"resty.rsa\"\nlocal pub, err = resty_rsa:new({\n    public_key = RSA_PKCS8_PUB_KEY,\n    key_type = resty_rsa.KEY_TYPE.PKIX,\n})\n\n-- creates a rsa object with pkcs#8 format of private key\nlocal priv, err = resty_rsa:new({\n    private_key = RSA_PKCS8_PASS_PRIV_KEY,\n    key_type = resty_rsa.KEY_TYPE.PKCS8,\n    -- you need to specify the password if the pkey is encrypted\n    -- password = \"foobar\",\n})\n```\n\n* `padding`\nSpecifies the padding mode when you want to encrypt/decrypt.\n* `algorithm`\nSpecifies the digest algorithm when you want to sign/verify.\n\n| `algorithm` value | meaning |\n| ------------------- | ------ |\n| md4/MD4/RSA-MD4/md4WithRSAEncryption | digest with `md4` |\n| md5/MD5/RSA-MD5/md5WithRSAEncryption/ssl3-md5 | digest with `md5` |\n| ripemd160/RIPEMD160/RSA-RIPEM160/ripemd160WithRSA/rmd160 | digest with `ripemd160` |\n| sha1/SHA1/RSA-SHA1/sha1WithRSAEncryption/ssl3-sha1 | digest with `sha1` |\n| sha224/SHA224/RSA-SHA224/sha224WithRSAEncryption | digest with `sha224` |\n| sha256/SHA256/RSA-SHA256/sha256WithRSAEncryption | digest with `sha256` |\n| sha384/SHA384/RSA-SHA384/sha384WithRSAEncryption | digest with `sha384` |\n| sha512/SHA512/RSA-SHA512/sha512WithRSAEncryption | digest with `sha512` |\n\nencrypt\n----\n`syntax: encrypted, err = obj:encrypt(str)`\n\ndecrypt\n------\n`syntax: decrypted, err = obj:decrypt(encrypted)`\n\n\nsign\n----\n`syntax: signature, err = obj:sign(str)`\n\nverify\n------\n`syntax: ok, err = obj:verify(str, signature)`\n\n\nPerformance\n========\n\nI got the result:\n```\nencrypt for 50000 times cost : 2.4110000133514s\ndecrypt for 50000 times cost : 57.196000099182s\nsign for 50000 times cost : 59.169999837875s\nverify for 50000 times cost : 1.8230001926422s\n```\n\nwhen I run this script.\n```\nlocal resty_rsa = require \"resty.rsa\"\nlocal algorithm = \"SHA256\"\n\nlocal rsa_public_key, rsa_priv_key, err = resty_rsa:generate_rsa_keys(2048)\nif not rsa_public_key then\n    ngx.say(\"generate rsa keys err: \", err)\n    return\nend\n\nlocal pub, err = resty_rsa:new({\n    public_key = rsa_public_key,\n    padding = resty_rsa.PADDING.RSA_PKCS1_PADDING,\n    algorithm = algorithm,\n})\nif not pub then\n    ngx.say(\"new rsa err: \", err)\n    return\nend\n\nlocal priv, err = resty_rsa:new({\n    private_key = rsa_priv_key,\n    padding = resty_rsa.PADDING.RSA_PKCS1_PADDING,\n    algorithm = algorithm,\n})\nif not priv then\n    ngx.say(\"new rsa err: \", err)\n    return\nend\n\n\nlocal num = 5 * 10000\n\nlocal str = \"hello test\"\n\nlocal encrypted, decrypted, err, sig, verify\n\nngx.update_time()\nlocal now = ngx.now()\n\nlocal function timer(operation)\n    ngx.update_time()\n    local t = ngx.now()\n\n    ngx.say(operation, \" for \", num, \" times cost : \", t - now, \"s\")\n    now = t\nend\n\nfor _ = 1, num do\n    encrypted, err = pub:encrypt(str)\n    if not encrypted then\n        ngx.say(\"failed to encrypt: \", err)\n        return\n    end\nend\n\ntimer(\"encrypt\")\n\nfor _ = 1, num do\n    decrypted = priv:decrypt(encrypted)\n    if decrypted ~= str then\n        ngx.say(\"decrypted not match\")\n        return\n    end\nend\n\ntimer(\"decrypt\")\n\nfor _ = 1, num do\n    sig, err = priv:sign(str)\n    if not sig then\n        ngx.say(\"failed to sign:\", err)\n        return\n    end\nend\n\ntimer(\"sign\")\n\nfor _ = 1, num do\n    verify, err = pub:verify(str, sig)\n    if not verify then\n        ngx.say(\"verify err: \", err)\n        return\n    end\nend\n\ntimer(\"verify\")\n```\n\n\nAuthor\n======\n\nDejiang Zhu (doujiang24) \u003cdoujiang24@gmail.com\u003e\n\nZexuan Luo (spacewander)\n\nRelease Steps\n=============\n\n1. update the `_VERSION` in `lib/resty/rsa.lua`\n2. update the `version` in `dist.ini`\n3. rename current rockspec to the new version and update the reference in it.\n4. tag the new version\n5. opm upload\n\nCopyright and License\n=====================\n\nThis module is licensed under the MIT license.\n\nCopyright (C) 2014-2018, by Dejiang Zhu (doujiang24) \u003cdoujiang24@gmail.com\u003e\nCopyright (C) 2018-, by Zexuan Luo (spacewander)\n\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:\n\n* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.\n\n* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\nSee Also\n========\n* the ngx_lua module: http://wiki.nginx.org/HttpLuaModule\n* the lua-resty-string: https://github.com/openresty/lua-resty-string\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fspacewander%2Flua-resty-rsa","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fspacewander%2Flua-resty-rsa","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fspacewander%2Flua-resty-rsa/lists"}