Code Monkey home page Code Monkey logo

lua-resty-string's Introduction

Name

OpenResty - Turning Nginx into a Full-Fledged Scriptable Web Platform

Table of Contents

Description

OpenResty is a full-fledged web application server by bundling the standard nginx core, lots of 3rd-party nginx modules, as well as most of their external dependencies.

This bundle is maintained by Yichun Zhang (agentzh).

Because most of the nginx modules are developed by the bundle maintainers, it can ensure that all these modules are played well together.

The bundled software components are copyrighted by the respective copyright holders.

The homepage for this project is on openresty.org.

For Users

Visit the download page on the openresty.org web site to download the latest bundle tarball, and follow the installation instructions in the installation page.

For Bundle Maintainers

The bundle's source is at the following git repository:

https://github.com/openresty/openresty

To reproduce the bundle tarball, just do

make

at the top of the bundle source tree.

Please note that you may need to install some extra dependencies, like perl, dos2unix, and mercurial. On Fedora 22, for example, installing the dependencies is as simple as running the following commands:

sudo dnf install perl dos2unix mercurial

Back to TOC

Additional Features

In additional to the standard nginx core features, this bundle also supports the following:

Back to TOC

resolv.conf parsing

syntax: resolver address ... [valid=time] [ipv6=on|off] [local=on|off|path]

default: -

context: http, stream, server, location

Similar to the resolver directive in standard nginx core with additional support for parsing additional resolvers from the resolv.conf file format.

When local=on, the standard path of /etc/resolv.conf will be used. You may also specify arbitrary path to be used for parsing, for example: local=/tmp/test.conf.

When local=off, parsing will be disabled (this is the default).

This feature is not available on Windows platforms.

Back to TOC

Mailing List

You're very welcome to join the English OpenResty mailing list hosted on Google Groups:

https://groups.google.com/group/openresty-en

The Chinese mailing list is here:

https://groups.google.com/group/openresty

Back to TOC

Report Bugs

You're very welcome to report issues on GitHub:

https://github.com/openresty/openresty/issues

Back to TOC

Copyright & License

The bundle itself is licensed under the 2-clause BSD license.

Copyright (c) 2011-2019, Yichun "agentzh" Zhang (章亦春) [email protected], OpenResty Inc.

This module is licensed under the terms of the BSD license.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  • Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  • 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.

THIS 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.

Back to TOC

lua-resty-string's People

Contributors

agentzh avatar bearnard avatar bungle avatar chase avatar dndx avatar jbochi avatar jinjiezhao avatar mibamur avatar miranovy avatar p0pr0ck5 avatar rfl890 avatar spacewander avatar thibaultcha avatar wzxjohn avatar xiaocang avatar zhuizhuhaomeng avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

lua-resty-string's Issues

Function missing to convert stored hex value back to Ascii for decrypt function

The functions you have are very good, but they make the assumption that if you want to encrypt and decrypt you will always have the encrypted ascii value (non-converted around). If you have to store this value into a cache table or dictionary there is no existing function (aside from atoi) to convert it back to something the decrypt function will take. So, there are two options:

  • provide a new function to convert any stored value back to ascii
  • change the decrypt function to handle hex and other data primitives

The code that I have had to use to invoke decrypt from a stored value. cache_key is supplied by an OS envvar.

local cache_key = os.getenv("ENCRYPT_KEY");

-- hex to char conversion, used to perform substitution
local c_table = {};
for jj = 0, 255 do
    c_table[("%02X"):format(jj)] = string.char(jj);
    c_table[("%02x"):format(jj)] = string.char(jj);
end

-- decryptIt function
local function decryptIt(value)
    local aes_128_cbc_md5 = aes:new(cache_key);
    return aes_128_cbc_md5:decrypt(value);
end

-- convert to ascii
local function convertAscii(value)
    return value:gsub("(..)", c_table);
end


local value = encryptIt(init_value);
.
. 
ngx.header['Set-Cookie'] = { "hash_val=" .. str.to_hex(value) ..   }
.
. ( a lot of code and reinvoke of proxy, etc... )
.
local url = ngx.var['cookie_hash_val'];
local d_crypted = decryptIt(convertAscii(url));

I think I have the above correct, but if you have any questions let me know.

是否能支持hex2byte

在lua-resty-string中已经实现to_hex,不知能否加一个from_hex,更加高效实现hex到byte的转换?
谢谢
我现在使用gsub的方式:

function from_hex(s)
    return (s:gsub('..', function(cc)
        return string.char(tonumber(cc, 16))
    end))
end

Question - resty_random.bytes vs math.random ?

Hi agentzth,

I came across your repo and i am wondering if in a goal to generate unique random numbers inside nginx i should use resty_random.bytes(16) versus the lua math.random.
What are the difference, would one be more unique or faster on high load ?

Thanks a lot

-seb

Is there an example of `AES-128 GCM with iv` decrypt

hi~
I try to decrypt AES-128 GCM, but failed.

function _M.test_gcm_decrypt2()
    local ngx_decode_base64 = ngx.decode_base64
	local test_enc = "keq0sOWsYgB1rWQmGkfca7VFvTVqE4v/gAVpaz+iaYe3ecpTUHKV9QKWPfhgNKwMG70v2lxe+kK8wLIt8awqGmpmKN9UYZgl3BdTEiwSkTDfJsMSkcr4Bw15fXGgzGyL1HL38ghPu82tPeXFT5rkmgIBbd7TZF4D90ulTOgUVFhRt+fjapz8mwj2fvItoQJ5K1PPhtMT0AwZpjRT1Hg03iWozK9CtX1M5ZX9VYT2g+Dmb+MQGB22+SCvVqThkoyqgQ3jD2wnrhHsqIqeWZ1ejAgLgtD8hp31DhGKC78eExjyDeEv/bLPbrpmZ462MNl95krVN0IbeDRmSfHatKt7y+aOiOuDnwOxTqXh6Cn/mxyA2nqQNqhNNdN/KLm4kiFSQbYEVV7U1+ed+AofkC2XEYo/dACexKU4VexT2aRVj2PdlHl9+MAg9NbfgFpkQG1Ox4k1eDxtla+yRk0zUKbTyJzl5PlydTnMfJwTFidNv6eCOBM01OlAIY6bNUnI6t7VjThlhOgc4i86yCUQy21Y7jGmWQSEDjilu/OLOIUhfdRdKyss62k41yPZEc2phWYkgsKarDODNlgn9v0ZVednDxO4/UB2kXgCd0w4AZUugpUK03C7wDsnjzkhzrJZpipkqVJCUzjtze2ckdJI9BImtl334knIva/5CkwXj7P5DoOE0aCrkBTKtBbBpGHOWNrvdwtGq9tCCP7FjvOvnqJyuW2g5Xq+VMn7m818uXpuVrRaC+eOh8ATRw1mqbrQbl93iVppqxo2k0FLCKkeG2TziPub8fEB9S/TSRxOrEKjctf5ZUi/bblSimtq4i3jzTiPbaMKhdZvruHNiwmzf473AgH1H51hZM67MNlY+WQglru5UY/gM0rYXHAy6G4rtFtyot2bff6w7rRV6N5v6pgk+qOVcyRdpr8+BTYDnD1g8y8OuHrwgUN60zJUuWfCJ7t79uou8UJD79Xw/ijDjw1MFI3VB16zi464YVjElX4T9xv2Imgr32W46QJJdHdM9RtlkHQ2t3NED9MYr4rMkqzDXC2a/kgYXmKzW0jFyks7EnNsPVPvMeamQs1sOiu+g4BGxzkP+FiC18Az2f502nQeIDuDRW3FcKTjqb1a9GH/qjVr3mYUVAaGykPz73lwnrbMHHAah4lMpXrvKIcrTDxTet2Sj4h6XOJIj73chbQ+HWdrbz1fwy6czrrpmekI2SVwgIooEIDS4wRLCBNNM4MxTxCHfDr0kmB2t3h9kGwgqdUJjeY68xK7B8rz+8JtDqHvwa+suK8/t4STHDE/Potgx/IUhlHG2V7BPkEoBShGnk+pRhXEDcGAgxfG2eloTeVaRF4BCqfgcErvuIIQQZ7w8OR2OvkuWnIi+oq2xYVPLyVAVY5UBDoneGWuc8gq2P+Y6AT1CLTrL+8skcEMMqDuEHPo2C7oVJy2s8fZffPEZFLMIQW+HS16NyieygbPsE9zs5smuUZfF2K45A6d4X3VDvxN4rsFoeOUvE8SuBO2CgMp7AsHLcrSEZRcuD3CTjaQAKF3RmjkwlF5LUPoEgV9DLvr2g6llW6OAM5Okc7OaXKFs7chTQVMN431LG2yj91BPaeDN1SmiL0nlmt/U5mERk6fMcTIMPKffnS8g7IMlkI4PYcnp6y2kPB48+X0R3vZ+jeOUem3U3z82fWYwsSbltLkwE1SCaCQpYmw2VLvWYQrpwUFUbYo2W+Wdk6Hi8b+y/PjVgWprkOGOYbXfwAKZHhC3DqX//CwImp5jaR8gcynYELD4KC1FYo/BQy1lNASqQFpfuBydsw9nKZGMudEa75AfLap0HEh8GE+6iodKasmfrLX5H8qEDOUF24eddo2/lnA//ZHOg462ZFk0GwiXGodqh34SYtLTImqzDV1FOJWXBWXZssyIBdF1saUfZTb4+kDcQvR2IUTVn+FQMkqj0dMYPtAclOCEzHv/daP9J+s94HNCWlJYd7qXlesTdL9hgdd2z4jwT+u2HldqDnMZ8GfyHuFUwYV96Ity983LwMXiWAWqE+qu59igdbBv02BduuoaoYOo7pbjNL05mgGfYkTZooKmNmLSuWyh2xSB8mW/MxWVQ6DXdKEWXqSkPfwr883piOSW2Kge8aLPZYu6mJPiU8fedJt2gSVC8wROigSxY5n7yBCv+YB7zC9oayP6SYCKHDCBD4sKpozdtOuRVCt0Ln0HUgBB74oJtBE9pJgMr9MhEh0ZH/y1m6FLdDdGgI1smHtwMhp/Rx3NzH9F41qI0E7RivBf4rB2wE7SoA+nCkt0k8eLAi9zKq5yU2ac5rr1MeKeq8v15vlto+C0XxkdGjJA+fEnW1G2dY3IVhwnrDbygYURqO4oj1x737Lj4UePSMpYT3PBAqHs7X0PHmB8ngFPzSYye3q5F/qN0JDExGN8VIt4V92xi7/WLJOHGNR/wrzNm0howejjPelZTRLVusugDTwezMhn5vPgkPMexfzd/MuzX/AxUSkPvT6CWA7pxzWZaDU5OZ5Qj47C7PW+R7Vgt5zSVX/RXMtVjeBIdd4z97K7r5WHv5JHF+o6ogr0IYwcFrG6eOUspjYlXj6UxfVz34oOdRS8IGcv6dvjXhb23+exbN7vzh/KBw9mJjYnZeZDsmv2wzeQ3oErAHVl+EK+P+Sl6lfsTaWD2Du41Ly87JHQwAJU0tPKL45d8ym3Y2tnMtEIQdCulGYUuKxL/LeZvfO2mapVvDzU8k/oTsmH1Fx++44X66syT6eQ7JAeHqWH755D1x4Ui+osBnLA+QladrpcU6UR1ySd6OK1lBCV7OrwurZgmzoGlqFxO1bUiHM6McV+UwG8krcqP67n/cUxKtcYwHCrmjtHffZWlSIsugKO7T+eK074NPZtOaREIEkPSkMv7afzeeHjUOzL04eSMmbi4HV1tx+a7VtKeqldHRWoyowe83Dd3PLR9panbJCL0qx+aG7PUocuQPN2QL5YARwn4P04JelOUFNWxHgjkN9k/iUmqrNjbir4j8WDsBuYubhwfJmel8aOTsh0Il27sDXHB1/VuDAXExOHeCmhexqog+i8dXfv5qNZnxG9TvbsALwBL5ZHQFi5PLSKXg2+EvMffBlKeqlwvbFxOxUleqMbF/mxUeOHwNXGHwmwT85SOh2c5B/3gZXihKUPf5/rEu2oQiaPmJz7WrjU0MrQ9PWW+a6M5AODKuxR4uWZ+V6+OJ7R0CTCbuSlbvh4leIDPzUufHTUsGu1L7i5vgfxznX3ZYqwsyzx/yFiP/zV2bzHCbZMBJEvYH8C0PfAZKSe0du2XhPagdzwHKzdhrSG7QxFXg93oFI4QJhVsoBbNTkq0uISHwVpgAVOAntuf7m8xGzOWqGnL16oiVztorONiWLbiefEHXCmz7eQQ2gVBK9serzLrmFQyHOLBBlRVDuYr+GSnW0ZdiiJnMbS1NEUhr1nRzgkmPrgVouXp4oyw0uL2/L3naDlE+HUUQ+d2eb0Deicn8JS9CCj9DD8bIz5kzySfcF4q+rcZQI62dyHC/cSqSDtAGuKYej6+CkrnNV3uNnmGKajSYmvX3p9+6/N9kphC4et6JGZmOy1zCduYIwhWlIIWjeqamsWUtIVcGxaBVdHfftSbW2Y05qMaYn+MA/hQLjbmhw5HFVY0OyJ6dsP9/dIxP3f7ayfX0ztuiDbyR9g1HsJpEjQblRFbGZonCv+d3JIXRWkBxf4VDHm/P72cpIKc3C/FXRqc3lMT+ew/Ja3ngN/xK7Th2A4O672n/j0rP0YppPolic/EZpUFwXeyov3ywiflTUm//fGZ3drPRtAgmvqv+63aaXbrJc0J4Dz/8JTQ6tv68NrSBZHCpW3MrKgoQRZ1vfwdIjvyzsI3EzA/41f4B2yugDoUzYUcbfPi6cQ5HnTrtr0cwakPm5tKkWtS1LT9sOQW661sZ64l1u97gvtj6pXbdGvNwz+ns9BVFRF1DE21SYBtql1k5kfjyYHKb6mHnJv+FYXtUrivR8GtkTKyBDfTHxTPdgGGA1xiPECPLyI7/6SRaxMF9nY10Vg72K8zEe3da7vJSjwH2ceIJhZZqrz2cfLbR/g37408B1Vebv84/cMyIAM/mBJ3fuZ5ScwZe4rzkOYxVAUUw3tFE5chvfphGnFSr9tD6/1zlpqryv0JvVnOWv0/DoLC5y7QhezeyriB+w9bxnAYpQ6Fwly1Y3dEM1VvC0LaVzRPjdS5pfRzZvRarF33tvDV+7Tj5c+OY6gUh6I+TBto/Jkfo64+YLKkdqOVo6cVwyRvTl8PVKIAFgQAoD83jkpw5EhKEbAjESSEnspymKO74uhHcyaV6jyL6ovfAS/NtUOQz7VG7nkncSA74hrP67+mmVHIdX9RgY3UmrL6q7oikLHK7xSoKqTu/uBD/VC2i7kaM3H2NBDlCS5xZd286hLK+fQA1LVo23Zb3GMY88HBmbErWUIppdZNkgRkQdPOcgQwvts5nRXvjkHRtTxxEj7k6QFzfWo7NraFC7igGeWeSuEIB1T83PJoCemNtTjWosg4MRnSidmVJmEfNt325jQMflKGuN1bC9chEEt2srjYdXIE1oHolYTreAlSlAopMdGqAr55U0l4bPXkbhRqLPv2QqEWpjDddKhoUVYxS1V41lI4r1Vjw9Pkoz0HqlpgfpRir/yBsVxvDv6XSFZgHA4em1gzbrK2pjJTpB7ysSV1p2ArvS/exDTELVQKMHV+KY/L/M3CyvgSJfO7UR1saJEq4zlmP2ZKdIk9U3alve2/D4Ya0IT7qPLWgO+ndcvetfgsXPc6UGWviaYQDvW8fYzaxoRQl+R7yecVXm9n896+tlpF1fYdwV9gtRZw0LuUnmL+8Wi8DH1sAsoUmTOmfikOojDJeCTY7M5Uqt1iDuQ0R+vtDm5QmxOIRafAWvOuDuVMUdeEIPlEGjjaVXDfKfTvtXFOxaqzK8q4an2cFYOjfbfiJYLcGwPWyKivIik24iuERXBxGflTB4OUmNAkB50jvkBFARBbEMVH6bTUMT3IZJJLSgn4CukyB0TDAqYhy7AtiiEPOGb7ZN0v2PhlHIgRIJsKIapSKsxmFqJkQRPjJASd1MSa7edFXPWLaKWvAJI3F8xKYy/idoB+IkE2ANtEilNC/yS5ogmG+KpXBsiLCKPrn/+pilG8D96dHv3bamTVC91jUES1S+tPL0SOzkOD1BmEPvQ52rhN2dZycdLIqBl9KmW3ooxGmF+erErByXIXjmXLuEQZsOFeHZQMsYGXH9Sp8LlmlhKezUsKfDx+0NH9igm9Zbrj7vq2a6x86OkHJ3+KTZSVKyRiryg2cJgFf7VOhpTvdLUXDWXM0Q17SQsCDvvkf95bYEtjfCXkx/L5WeLK+7junrFriV5bPembrjiz8Ku8G4YZhjnSCt+Lj1u7SNgX9KVOPw40T3+xsrdmO4R4CKXki5cZfgwqxXBeYk76/NcUkvG127/PuUls+tjQ5GcjyEm4mDB4+vMprjeU8IDgYqeGhgJ/RIFz+OEY8tOy0ZdOZGnHXn3h5QqCvIWc27UiA4C4/GwwaGx6PGmehxMknuTwjM0Lz7IJI48ofONe4EkJPrm9g48b5+dG5jNMONo1FF3xXB+A5M6DMugeRtWyMaOLIeOgVwBWJUuT9SKj6AXEKG1GHIP1243SmHF/kN0Wm8tcydJZyQuSlGDQ/i95w1/uqt8TEDeekAkXKel5v+1c5HdtnFNpq19+NQbrITD7m8DJwTH4+VbfR4we6I0VUAwOpwn0qRgMZRZbvfiMIfgppjK02KW4wKbHrV75av5RIyIbXyCGNLX+0cVcRBH17qayeAGJppKBbKAixShlig2ynIr7BEGP551sJQ76EwdJ2qLUfHC9NA/NT4XZdzEvxknMm6DckbgC6VVOcppQ4gQGXcc2Ci2o5RsBXaGz8VUUk5ydyDsssEKxg5nD/lA2CcIDgyu3+qViyy+33014HvvjFNVlLdbcW1dY5AvN+LpMbA/8U9echgH2bcGgWA+xsZaJUXRF6/mdeUVrE+8L1icxTqRmFVdup0yuNaOxftG6c3f05Lz0b0qN/TwT6vvBqKO9vt9IlqtJXQnGQ+vY7P0WO8Uir2vqxYhZK4GcvBgKM0doE="
	local test_key = "4AvVhmFLUs0KTA3Kprsdag=="
	local test_iv = "vN2mBu17W/8Ewfg3AX8Ayg=="

    local enc = ngx_decode_base64(test_enc)
    local key = ngx_decode_base64(test_key)
    local iv = ngx_decode_base64(test_iv)

    local decryptor = aes:new(key, nil, aes.cipher(128, "gcm"), {iv = iv}, nil, nil, false)
    if not decryptor then
        return false
    end

    local plaintext, err = decryptor:decrypt(enc, "")
    ngx.log(ngx.ERR, "err: ", err)
    if not err and plaintext then
        return true
    end
end

but, it can be decrypt by python and golang:

def test_gcm_decode():
    test_enc = "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"
    test_key = "4AvVhmFLUs0KTA3Kprsdag=="
    test_iv = "vN2mBu17W/8Ewfg3AX8Ayg=="
    enc = base64.b64decode(test_enc)
    key = base64.b64decode(test_key)
    iv = base64.b64decode(test_iv)
    mode = AES.MODE_GCM

    decryptor = AES.new(key, mode, iv)
    plaintext = decryptor.decrypt(enc)
    print(plaintext)
func decodeAesGcmTest() {
	test_enc := "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"
	test_key := "4AvVhmFLUs0KTA3Kprsdag=="
	test_iv := "vN2mBu17W/8Ewfg3AX8Ayg=="
	key, _ := base64.StdEncoding.DecodeString(test_key)
	byteKey := []byte(key)
	add := []byte("")
	block, _ := aes.NewCipher(byteKey)
	aesgcm, _ := cipher.NewGCMWithNonceSize(block, 16)

	iv, _ := base64.StdEncoding.DecodeString(test_iv)
	enc, _ := base64.StdEncoding.DecodeString(test_enc)
	plaintest, _ := aesgcm.Open(nil, iv, enc, add)
	fmt.Println("plaintest: ", string(plaintest))
}

Is the method I am using is wrong?
Thank you~

Can we have str.from_hex() function?

pretty much the opposite of:

function _M.to_hex(s)
    local len = #s * 2
    local buf = ffi_new(str_type, len)
    C.ngx_hex_dump(buf, s, #s)
    return ffi_str(buf, len)
end

Documentation Clarification

@agentzh

The example documentation for resty.random.bytes() contains a while loop. Is there a situation where resty.random.bytes() can return nil, or is this an error in the documentation?

    local resty_random = require "resty.random"
    local str = require "resty.string"
    local strong_random = resty_random.bytes(16,true)
        -- attempt to generate 16 bytes of
        -- cryptographically strong random data
    while strong_random == nil do
        strong_random = resty_random.bytes(16,true)
    end
    ngx.say("random: ", str.to_hex(strong_random))

return null when i using lua aes model( cbc 128) decrypt data

  • I installed the subsystem(ubuntu) under win10,and installed openresty via apt-get, and installed luarocks 2.4 、lapis 1.7。

    When i learn openresty, i found the aes model always return null。。。。the code like this:
        local aes = require "resty.aes"
        local str = require "resty.string"
        local iv = ngx.decode_base64(self.params.iv)
        local data = ngx.decode_base64(self.params.encryptedData)
        local sessionKey = ngx.decode_base64self.params.sessionKey)
        local myAes  = assert(aes:new(sessionKey, nil, aes.cipher(128, "cbc"), {iv=iv, method=nil}))
        print(json.encode(myAes:decrypt(data ))) --  -> show null
  • And the system report: 2018/05/09 14:17:13 [alert] 47#47: ignoring stale global SSL error (SSL: error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt)

lua use resty.aes Encrypted hex result diff from c++ use openssl

the same key and the same mesg, but the result is different, why?
lua:
local key = "1"
local mesg = "2"

local aes_256_cbc_sha1x5 = aes:new(key, salt, aes.cipher(256,"cbc"), aes.hash.sha1, 5)
local encrypted = aes_256_cbc_sha1x5:encrypt(mesg)
ngx.say("AES 256 CBC (SHA-1, salted) Encrypted HEX: ", str.to_hex(encrypted))

AES 256 CBC (SHA-1, salted) Encrypted HEX: 619a1da54b6c5113eb335a74296fed54

c++:
int i, nrounds = 5;
unsigned char key[32], iv[32];

i = EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha1(), NULL, key_data, key_data_len, nrounds, key, iv);

...
hex:1671d15e1905d518201b35064043cb71

to_hex api invoke ngx_hex_dump, it developed by C , same to my own c++ coding, but the result's display is different, Why???

aes.lua: `s` passed to `_M.encrypt` appears to be table?

I get the following error upon attempting to call encrypt.

site/lualib/resty/aes.lua:191: bad argument #4 to 'EVP_EncryptUpdate' (cannot convert 'table' to 'const unsigned char *')

The Lua script is nothing fancy:

local aes = require "resty.aes"
local cipher = aes:new("secretKey")
local encryptedData, err = cipher:encrypt(sessionData)
if not encryptedData then
  return err
end

If I shadow the s variable in _M.encrypt(self, s), e.g. by doing local s = "foo", then the error disappears, so it definitely is s that is the issue although I am not sure why s is a table to begin with.

resty.aes 解密时遇到的奇怪输出

  • key 是 sha256 的 livid 这个字符串(用 Python 生成 HEX 和 Base64 两种格式):
hashlib.sha256("livid").hexdigest()
'7e2f4e39a5fa1e10f5fb47b8387ba6fb1da8e5a59250b88cfc1f51d4d6027247'

base64.b64encode(hashlib.sha256("livid").digest())
'fi9OOaX6HhD1+0e4OHum+x2o5aWSULiM/B9R1NYCckc='
  • 用这个 key 的 HEX 格式在 openssl 用 aes-256-cbc 加密原文(64 个小写的 a)并得到 Base64 格式的结果:
echo -n "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" | openssl aes-256-cbc -a -e -nosalt -K "7e2f4e39a5fa1e10f5fb47b8387ba6fb1da8e5a59250b88cfc1f51d4d6027247" -iv 0

P9oS+dZavs7oRMa4cQSAKeG92LT3KAOO7TMgvS8OcRrhV05jUfOKQzERbzynWBFw
Dq/YEwDuJ+qG1hYh42Vk2z5tXVZjBj75jBE0GtAiT6o=

openssl 里必须指定 -nosalt 和 -iv 0,因为我这边需求里客户的输入就是用这个配置生成的。

  • 在 resty string 里解密刚才从 openssl 里生成的 Base64 密文,resty string 的代码:
location / {
        content_by_lua '
        local aes = require "resty.aes"
        local string = require "resty.string"
        local aes_256_cbc = aes:new(ngx.decode_base64("fi9OOaX6HhD1+0e4OHum+x2o5aWSULiM/B9R1NYCckc="), nil, aes.cipher(256, "cbc"), {iv = "0000000000000000"})
        local decrypted = aes_256_cbc:decrypt(ngx.decode_base64("P9oS+dZavs7oRMa4cQSAKeG92LT3KAOO7TMgvS8OcRrhV05jUfOKQzERbzynWBFwDq/YEwDuJ+qG1hYh42Vk2z5tXVZjBj75jBE0GtAiT6o="))
        ngx.say(decrypted)
        ';
}
  • 从 resty string 里解出来的结果是这样的:

QQQQQQQQQQQQQQQQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

但是原文其实是 64 个 a:

aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

reproduce aes.lua in openssl

Hi
This is not an issue, more of a request for clarification
I am trying to encrypt with openssl and decrypt with aes.lua and vice-versa but I can't find the right configuration (and so it produces incompatible output)

please consider your example

location /ENCTEST/
{
    content_by_lua '
        local aes = require "aes"
        local decrypt = require "decrypt"
        local aes_128_cbc_md5 = aes:new("AKeyForAES")
            -- the default cipher is AES 128 CBC with 1 round of MD5
            -- for the key and a nil salt
        local encrypted = aes_128_cbc_md5:encrypt("Secret message!")
        local hex = decrypt.tohex(encrypted)
        ngx.say("AES 128 CBC (MD5) Encrypted HEX: " .. hex)
    ';
}
# curl localhost/ENCTEST/
--> AES 128 CBC (MD5) Encrypted HEX: 6D87D6B11C6BF0DCB76D1AA611520B3C

then when I try to do "the same" in openssl:

# cat password.txt message.txt 
AKeyForAES
Secret message!
# openssl enc -aes-128-cbc -nosalt -pass file:password.txt -in message.txt -out message.enc
# xxd -p message.enc
--> 4a04ab272df45bbe85b11cc28633b2734b0a5e3ec7264d56af45bde5c0c7
76d6

Many thanks as always,
Richard

this library is still experimental?

Hey, i am wondering if this library is still experimental or safe to use in production systems? Also if anyone knows the support of "AES" encryption methods?

Thanks

how can i decrypt the string?

local aes = require "resty.aes"
local str = require "resty.string"
local aes_128_cbc_with_iv = assert(aes:new("0000000000000000", nil, aes.cipher(128,"cbc"), {iv="0000000000000000"}))
local encrypted = aes_128_cbc_with_iv:encrypt("xxxx")
encrypted = str.to_hex(encrypted)

as this , i can get the result : encrypted. and it is equal which encrypt by php.
but , if someone give me the encrypted string , how can i decrypt the string?

aes.lua如何用ecb+no padding+no iv+sha256来加密

我的做法是:

local aes_key = "edbafb26bdddad1e1b79817b570afee5"
local aes_256_ecb_sha256 = aes_resty:new("AKeyForAES-256-ECB"
    , aes_key
    , aes_resty.cipher(256, "ecb")
    , aes_resty.hash.sha256
)

local encrypted = aes_256_ecb_sha256:encrypt(
    "827ccb0eea8a706c4c34a16891f84e7b"
)
-- ngx.log(ngx.ERR, "AES 256 ECB (SHA-256) Encrypted HEX: ", string_resty.to_hex(encrypted))
ngx.log(ngx.ERR, "AES 256 ECB (SHA-256) Encrypted HEX: ", string_resty.to_hex(encrypted))

ngx.log(ngx.ERR, "AES 256 ECB (SHA-256) Decrypted: "
    , aes_256_ecb_sha256:decrypt(encrypted))

加密出来的结果和其他人一直对不上,是哪里出问题了吗?紧急求助

aes.lua with aes.js

Hi,

I'm try to use aes.lua with aes.js

I see the default configure is
local aes_128_cbc_md5 = aes:new("AKeyForAES")
-- the default cipher is AES 128 CBC with 1 round of MD5
-- for the key and a nil salt

what is the mean?

I know aes 128 Secret Key length must be 16
so need get md5 of the given password "AKeyForAES"?
1 round of MD5 mean just md5(password)?
if 2 round of MD5 shoule be md5(md5(password)) ?

Thank you very much

how to implement aes-128-ecb encryption with php or golang

here is the lua code

local aes = require 'resty.aes'

local cipher = aes:new('0123456789123456', nil, aes.cipher(128, 'ecb'))

print(ngx.encode_base64(cipher:encrypt('foobar')))

the output should be rTeNAHEZtzsyn1dDAujGgQ==

blow is my php code

var_dump(base64_encode(openssl_encrypt('foobar', 'aes-128-ecb', '0123456789123456', OPENSSL_RAW_DATA)));

the output should be AIIiZT3RO/bkseLE0Mcopg==

how can i get the lua result with php code. pls help me, thanks.

Failed to find function EVP_md5

My Lua code looks like so:

local aes = require 'aes'
cipher = aes.encrypt('password', 'secret');

When I run it from the command line:

$ lua unit.lua

I get this error message:

lua: /usr/local/openresty/lualib/resty/aes.lua:106: failed to find function/global EVP_md5 stack traceback: [C]: ? /usr/local/openresty/lualib/resty/aes.lua:106: in main chunk [C]: in function 'require' /usr/local/openresty/nginx/test/unit_tests.lua:4: in main chunk [C]: ?

What is wrong with that and how can I fix it?

the limit of luajit table ??

249577944 items is not very big at my In my opinion,but luajit just overflow , so whats the limit ?? Can be overcome ??

tb = table.new(249577944,0)
table overflow
stack traceback:
[C]: in function 'new'
stdin:1: in main chunk
[C]: at 0x004051e0

tb = {}
for i = 1, 449577944 do

tb[i] = "abcd"..i
end
PANIC: unprotected error in call to Lua API (stdin:2: table overflow
stack traceback:
stdin:2: in main chunk
[C]: at 0x004051e0)

ecb模式下 pkcs7如何设置

aes:new("1234567890123456",nil,aes.cipher(128,"ecb"),nil)
加密出来字符客户端不能解密,似乎是 pkcs7没设置,请问该如何设置?

calling directive set_decode_hex failed with code -1

decoded = ndk.set_var.set_decode_hex(encoded);

it works when encoded is correct, but if I pass something like NotACorrectEncodedString as encoded to nginx, it will fail and say calling directive set_decode_hex failed with code -1 return a 500 code

I wan to suppress the error message, handle the exception myself, something like

decoded = ndk.set_var.set_decode_hex(encoded);
if decoded.failed then
--....

How can I do that?

Unable to decrypt cipher encrypted by Crypto-JS (AES default)

Hello,
I am not able to decrypt back what was encrypted using Crypto-JS in browser Javascript / NodeJS:

// Encrypt
var ciphertext = CryptoJS.AES.encrypt('testingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtesting', '&&nH8P3bxk+?C4gR');
 
// Decrypt
var bytes  = CryptoJS.AES.decrypt(ciphertext.toString(), '&&nH8P3bxk+?C4gR');
var plaintext = bytes.toString(CryptoJS.enc.Utf8);

console.log(plaintext);

I can decrypt it in Java using:
Cipher.getInstance("AES/CBC/PKCS5Padding")
But, I get
nil
when I try to do it with resty.aes. Here is the code:

local aes = require "resty.aes"
local cipher = aes.cipher(256)
local aes_256_cbc_md5 = aes:new('&&nH8P3bxk+?C4gR', nil, cipher)

local cipherText = 'U2FsdGVkX1859eIyt4M7VHNBl9BGMdsemPYAADKmqs9sltwKINfzVMci0Vw1NLr73Iti67zQ0+JoqVcL59Gcp+4R5NY6wg2n3r0wqLcQRc7PkIGpgup1UJp4DzhXSIGHz08Eu/nEbt3jAh3S4GVUoVFbXLluf/BvedTGdsqcN2EPL9S/WQOc5QDyl9OQjpBl+QS56nWL0DO6iR/6CIoEuQ+zC/7KTpBw2jQf8sxuDNptZzwKLlDi2sWSaeCkvPj+m8zheAlnZzVc+L5JeLdcx7WkIRQImNs9P5bkhXmiK2nZnw4yco3QHbzRkRBJiB3HgdYDauHsuKmR21zv9VLjAcGTrZjiUbtrBfuTRawKOiAFm599Inbq+Ugu9n4RelQ2CTdxwDfe3ZE3kscP3dyAmg=='
ngx.say(aes_256_cbc_md5:decrypt(cipherText))

Could someone please help me with server side decryption?

why the result is wrong

when I use 128_ecb, first encrypt the content, then base64, why the result is wrong, is it exist a bug that it default use md5 to encode the key then use to encrypt? I just want to use the origin key

AES GCM with AAD support

Currently aes.lua only support AES GCM with tag, but does not support AAD (Additional Authenticated Data). Could someone please add AAD support in AES GCM mode?

aes.lua貌似有些不对劲

你好,春哥
查看源码,感觉好像password(salt)没有起做用,使用的是key做为password了,那么,只有在lua下加密,lua下解密了,和其他语言无法交换数据!
代码片段

local aes = require "resty.aes"
local str = require "resty.string"
local hash = {
        iv = "fedcba9876543210",
        method = nil
}
local salt = "0123456789abcdef"
local data = "hello"
local aes_128_cbc, err = aes:new("AKeyForAES128CBC", salt, aes.cipher(128,"cbc"), hash)
if err  then
        ngx.say(err)
        ngx.exit(200)
end
local encrypted = aes_128_cbc:encrypt(data)
ngx.say("AES 128 CBC Encrypted HEX: ", str.to_hex(encrypted) .. "<br />")
ngx.say("AES 128 CBC Decrypted: ", aes_128_cbc:decrypt(encrypted))

屏幕回显是

AES 128 CBC Encrypted HEX: 5dff16410bf805de1d14d96fbffcab7c
AES 128 CBC Decrypted: hello

这里我使用了AKeyForAES128CBC 做为key,但这个更好的写法应该是aes-128-cbc,或者说这个key跟本也没有什么用吧,因为后面的cipher才确定了使用什么算法,因为我要自定义向量iv,查看源码结构,构造了一个hash table,确定初始化向量,这样问题就来了,这个key你源代码里写的一个检查长度,以上面为例,则必须是长度16,

好的,也这可以,但是在下面生成gen_key的时候,你使用的就是这个key,而不是salt,
当我将源码中的#key改成#salt,key改成slat后,得到的结束是正确的,另一种不指定hash或指定一个hash在aes中的hash table中的一个算法时,不知道有没有问题,可能也有问题,因为貌似也使用到了key

我不清楚这个key与salt的区别,不知道你的初衷是key只做为一个描述存在的吗?如果参与计算,貌似比较麻烦。
下面是php的代码片段

<?php
$iv = 'fedcba9876543210';
$salt = '0123456789abcdef';
$data = 'hello';
echo bin2hex(openssl_encrypt($data, "aes-128-cbc", $salt, true, $iv));

屏幕回显是

7bedceb0655f38941069789f36462091

help: Is the option `salt` in `new` function in `aes.lua` file mean initialization value?

Hi~
I am reading python code about Crypto.Cipher in website: https://www.pycryptodome.org/src/cipher/classic#ctr-mode
I found the new function defined to Crypto.Cipher.<algorithm>.new(key, mode, *, nonce=None, initial_value=None, counter=None)
Is the initial_value means the salt in :

function _M.new(self, key, salt, _cipher, _hash, hash_rounds, iv_len, enable_padding)

Thank you~

lua aes ECB 128 decrypt error

I tryed encrypt a text with a key with PHP code,then it is OK when decrypt it with Java and Object-C ,

 mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $bindkey, $text, MCRYPT_MODE_ECB )

I dont know why do you need a sha1 when I just want want decrypt a ECB mode string

local aes_default = aes:new(key,nil,
aes.cipher(128,"ecb"),aes.hash.sha1)

I can not set aes padding

I want to use a custom padding format, but I can't.

please add EVP_CIPHER_CTX_set_padding to ffi config of aes, thanks.

Using byte arrays for key and iv with AES-128 enc/dec

Hello-

I’ve been looking at the lua-resty-string module to do some aes-128 decryption in Lua.

I have the AES secret key, but it’s not a string- it’s a binary file, and the best I can do is convert it into an array of 16 bytes. I also have the IV, which is an array of 16 bytes of '0'.

I’m looking at the below example from https://github.com/openresty/lua-resty-string:

local aes_128_cbc_with_iv = assert(aes:new("1234567890123456",
        nil, aes.cipher(128,"cbc"), {iv="1234567890123456"}))

I'm assuming that the first instance of "1234567890123456" is the key, and the second one is the iv.

How should I format the array of bytes that I have for the secret key and the IV into the String formats that will be acceptable for the above example? Is it possible at all, and if so- is there a specific encoding that I have to use to convert those byte arrays to strings?

A problem in aes:new when i use raw key with aes-256-ecb

openssl test:

key=abcdef12345600000000000000000000
hex(abcdef12345600000000000000000000) = 6162636465663132333435363030303030303030303030303030303030303030
echo -n 'just a test' | openssl aes-256-ecb -K 6162636465663132333435363030303030303030303030303030303030303030 -base64

openssl output:
5ole1XZnDeOUBMN7QRrhEQ==

openresty test:

local t_plain = "just a test"
local t_key = "abcdef12345600000000000000000000"
local t_aes = aes:new(t_key, nil, aes.cipher(256, "ecb"), nil)
local t_cipher = t_aes:encrypt(t_plain)
ngx.say(ngx.encode_base64(t_cipher))

but openresty output is:
USAXTRh/5sFk8pxyEF/WOg==

Does something wrong when i initialize the t_key with aes:new function?
Then, I checked the aes.new source code in https://github.com/openresty/lua-resty-string/tree/master/lib/resty/aes.lua, l got following message:

function _M.new(self, key, salt, _cipher, _hash, hash_rounds)
     local _hash = _hash or hash.md5
     if type(_hash) == "table" then
           ...
     else:
           if C.EVP_BytesToKey(_cipher.method, _hash, salt, key, #key,hash_rounds, gen_key, gen_iv)
     end
     if C.EVP_EncryptInit_ex(encrypt_ctx, _cipher.method, nil, gen_key, gen_iv)
           ...                                                                                 

It seems that you must choose a hash method for key, and use openssl C.EVP_BytesToKey to return new key - gen_key.
How can i use aes:new with the raw hex key just as i have used in openssl command?
thanks~

500 internal error when using test.lua

Hi. I'm very new to lua. What could I be missing? Here is the error I'm getting on my nginx's error.log

	no file './resty/sha1.so'
	no file '/usr/local/lib/lua/5.1/resty/sha1.so'
	no file '/usr/local/lib/lua/5.1/loadall.so'
	no file './resty.so'
	no file '/usr/local/lib/lua/5.1/resty.so'
	no file '/usr/local/lib/lua/5.1/loadall.so'
stack traceback:
coroutine 0:
	[C]: in function 'require'

I searched the whole file sytem but I didn't find them. How do I install it?

no hash for aes-128-ecb

the code same with :

<?php
var_dump(openssl_encrypt('foobar', 'aes-128-ecb', '0123456789123456'));

is :

local aes = require 'resty.aes'

local cipher = aes:new('0123456789123456', nil, aes.cipher(128, 'ecb'), {
    iv = '0000000000000000'
})

print(ngx.encode_base64(cipher:encrypt('foobar')))

use a fake iv that will not be used by openssl on ecb mode for aes, and resty.aes will use password directly without hash.

AES-256 CTR not declared

I need to use AES 256 CTR, however it isn't declared in aes.lua:

runtime error: /usr/local/openresty/lualib/resty/aes.lua:120: missing declaration for symbol 'EVP_aes_256_ctr'

Could you add that please?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.