├── LICENSE ├── README.md ├── src ├── Makefile └── codec.c └── test ├── test.lua ├── test_aes.lua ├── test_base64.lua ├── test_hmac_sha1.lua ├── test_md5.lua ├── test_rsa_encrypt_decrypt.lua └── test_rsa_sign_verify.lua /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 马世界 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | lua-codec工具包 2 | ======================================================= 3 | 鉴于网上很难找全相应的Lua工具,或者难用的要死,因此创建本项目; 4 |
5 | 基于openssl,实现常用的加密、摘要算法的Lua工具包,如hmac, md5, aes, rsa等,具体功能参见示例代码; 6 | 7 | 编译说明 8 | ------------------------------------------------------- 9 | 我是基于LuaJIT-2.0.3和openssl 1.0.0编译的,可以根据你的环境改codec.c的include以及Makefile; 10 | 11 | cd src/ 12 | make 13 | mv codec.so $YOUR_LUA_PACKAGE_PATH(如:/usr/local/lib/lua/5.1) 14 | 15 | 16 | Lua代码示例 17 | ------------------------------------------------------- 18 | 19 | ### BASE64编解码 20 | local codec = require('codec') 21 | local src = '123456' 22 | local dst = codec.base64_encode(src) 23 | print(dst) 24 | 25 | local dsrc = codec.base64_decode(dst) 26 | print(dsrc) 27 | 28 | assert(dsrc == src) 29 | 30 | ### MD5编码 31 | local codec = require('codec') 32 | local src = '123456' 33 | local dst = codec.md5_encode(src) 34 | print(dst) 35 | assert('e10adc3949ba59abbe56e057f20f883e' == dst) 36 | 37 | ### HMAC-SHA1编码 38 | local codec = require('codec') 39 | local src = '123456' 40 | local dst = codec.hmac_sha1_encode(src) 41 | print(dst) 42 | assert('06285a0e4a99a56f7f9d1e239acad4de7c79ebe9' == dst) 43 | 44 | ### AES-ECB-PKCS5Padding加解密 45 | local codec = require('codec') 46 | local src, key = '123456', '0123456789abcdef' 47 | local bs = codec.aes_encrypt(src, key) 48 | local dst = codec.base64_encode(bs) 49 | print(dst) 50 | 51 | local dbs = codec.base64_decode(dst) 52 | local dsrc = codec.aes_decrypt(dbs, key) 53 | print(dsrc) 54 | 55 | assert(dsrc == src) 56 | 57 | ### SHA1WithRSA私钥签名及公钥验签 58 | local codec = require('codec') 59 | local src = '123456' 60 | local privpem = [[-----BEGIN RSA PRIVATE KEY----- 61 | MIICXAIBAAKBgQCsxjKD2lnmkmELoo5QphM/VdREJKym26R0T+19JDa3MVZFDbwg 62 | UGT8XM8bElrKgxexhTVRt07btyIejdbiPx7sCbWcVP8peZI+QZEVVzaE2Ci5n0lP 63 | 9v9GUSl0QfZU94uIwl++BVq0VFvbHax/R/q4oTRD1u73ASM27QW42+cJFwIDAQAB 64 | AoGALHoNMQI52HBgSSV8q2hFVi2bKjuisoWibUrSIT/8UeaChd5GSq9Hf+vIaPit 65 | pKpgpBNdqX6d71PSlbj/01hadg5IxrGWQZWzT/3IzuhTxAu4TkztUJelGRcM6ykZ 66 | 5AxijiIxTLWSY/ygtEaM2QShhl8dCReNT+oIDGf/iMSTVykCQQDl07WZR9ATReVc 67 | vM7/v9iiz/g1Tj9/8AOuyYOZ5kp5a8IAr48dXixzuTZY66RwPj/J5vrzLuHc7Uc0 68 | RAi4hgmTAkEAwHMxP0KVOzDH49SsiUjfOycqrBl68QCXUWQj2mi7Bb1pLryoYDFv 69 | FTuk6pxKyfr5O8M2s8thTz6f3EO7hFqk7QJAdX8Ly2ZkYUYNoaDBbwzEk1AhhBcR 70 | 7bVmHJjXV/ndP0Aw+arHTutTbIJW35TxB5U7hVw6FdN1Ez6XdYgGsVeNUwJAEjlW 71 | SoVFmGtQInT7Oaza5sEYu19WUwgZTC3Nb1tHio2bLj/TOfi0ajBRt53BP0sy2sPr 72 | pC74MgbeIH+RfEERKQJBAIpPkQztkbpZwD9gDiK86U+HHYZrhglxgfDIXYwTH3z/ 73 | KCrfyNxiH2im9ZhwuhLs7LDD7wDPHUC5BItx2tYN10s= 74 | -----END RSA PRIVATE KEY-----]] 75 | local bs = codec.rsa_private_sign(src, privpem) 76 | local sign = codec.base64_encode(bs) 77 | print(sign) 78 | 79 | local dbs = codec.base64_decode(sign) 80 | local pubpem = [[-----BEGIN PUBLIC KEY----- 81 | MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCsxjKD2lnmkmELoo5QphM/VdRE 82 | JKym26R0T+19JDa3MVZFDbwgUGT8XM8bElrKgxexhTVRt07btyIejdbiPx7sCbWc 83 | VP8peZI+QZEVVzaE2Ci5n0lP9v9GUSl0QfZU94uIwl++BVq0VFvbHax/R/q4oTRD 84 | 1u73ASM27QW42+cJFwIDAQAB 85 | -----END PUBLIC KEY-----]] 86 | local typ = 2 87 | local ok = codec.rsa_public_verify(src, dbs, pubpem, typ) 88 | assert(ok) 89 | 90 | rsa_public_verify最后一个参数为公钥串类型,1:PEM 2:PKCS8 91 | 就是“-----BEGIN RSA PUBLIC KEY-----”和“-----BEGIN PUBLIC KEY-----”的区别,啦啦啦 92 | 93 | ### RSA公钥加密及私钥解密 94 | local codec = require('codec') 95 | local src = '123456' 96 | local pubpem = [[-----BEGIN PUBLIC KEY----- 97 | MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCsxjKD2lnmkmELoo5QphM/VdRE 98 | JKym26R0T+19JDa3MVZFDbwgUGT8XM8bElrKgxexhTVRt07btyIejdbiPx7sCbWc 99 | VP8peZI+QZEVVzaE2Ci5n0lP9v9GUSl0QfZU94uIwl++BVq0VFvbHax/R/q4oTRD 100 | 1u73ASM27QW42+cJFwIDAQAB 101 | -----END PUBLIC KEY-----]] 102 | local typ = 2 103 | local bs = codec.rsa_public_encrypt(src, pubpem, typ) 104 | local dst = codec.base64_encode(bs) 105 | print(dst) 106 | 107 | local privpem = [[-----BEGIN RSA PRIVATE KEY----- 108 | MIICXAIBAAKBgQCsxjKD2lnmkmELoo5QphM/VdREJKym26R0T+19JDa3MVZFDbwg 109 | UGT8XM8bElrKgxexhTVRt07btyIejdbiPx7sCbWcVP8peZI+QZEVVzaE2Ci5n0lP 110 | 9v9GUSl0QfZU94uIwl++BVq0VFvbHax/R/q4oTRD1u73ASM27QW42+cJFwIDAQAB 111 | AoGALHoNMQI52HBgSSV8q2hFVi2bKjuisoWibUrSIT/8UeaChd5GSq9Hf+vIaPit 112 | pKpgpBNdqX6d71PSlbj/01hadg5IxrGWQZWzT/3IzuhTxAu4TkztUJelGRcM6ykZ 113 | 5AxijiIxTLWSY/ygtEaM2QShhl8dCReNT+oIDGf/iMSTVykCQQDl07WZR9ATReVc 114 | vM7/v9iiz/g1Tj9/8AOuyYOZ5kp5a8IAr48dXixzuTZY66RwPj/J5vrzLuHc7Uc0 115 | RAi4hgmTAkEAwHMxP0KVOzDH49SsiUjfOycqrBl68QCXUWQj2mi7Bb1pLryoYDFv 116 | FTuk6pxKyfr5O8M2s8thTz6f3EO7hFqk7QJAdX8Ly2ZkYUYNoaDBbwzEk1AhhBcR 117 | 7bVmHJjXV/ndP0Aw+arHTutTbIJW35TxB5U7hVw6FdN1Ez6XdYgGsVeNUwJAEjlW 118 | SoVFmGtQInT7Oaza5sEYu19WUwgZTC3Nb1tHio2bLj/TOfi0ajBRt53BP0sy2sPr 119 | pC74MgbeIH+RfEERKQJBAIpPkQztkbpZwD9gDiK86U+HHYZrhglxgfDIXYwTH3z/ 120 | KCrfyNxiH2im9ZhwuhLs7LDD7wDPHUC5BItx2tYN10s= 121 | -----END RSA PRIVATE KEY-----]] 122 | local dbs = codec.base64_decode(dst) 123 | local dsrc = codec.rsa_private_decrypt(dbs, privpem) 124 | print(dsrc) 125 | assert(dsrc == src) 126 | 127 | rsa_public_encrypt最后一个参数为公钥串类型,1:PEM 2:PKCS8 128 | 就是“-----BEGIN RSA PUBLIC KEY-----”和“-----BEGIN PUBLIC KEY-----”的区别,再啦啦啦 129 | -------------------------------------------------------------------------------- /src/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | gcc -Wall -O2 -shared -o codec.so codec.c -lluajit-5.1 -lcrypto 3 | 4 | clean: 5 | rm -f codec.so 6 | -------------------------------------------------------------------------------- /src/codec.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | /** 13 | * BASE64编码 14 | * 15 | * LUA示例: 16 | * local codec = require('codec') 17 | * local bs = [[...]] --源内容 18 | * local result = codec.base64_encode(bs) 19 | */ 20 | static int codec_base64_encode(lua_State *L) 21 | { 22 | size_t len; 23 | const char *bs = luaL_checklstring(L, 1, &len); 24 | BIO *b64 = BIO_new(BIO_f_base64()); 25 | BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); 26 | BIO *bio = BIO_new(BIO_s_mem()); 27 | bio = BIO_push(b64, bio); 28 | BIO_write(bio, bs, len); 29 | BIO_flush(bio); 30 | BUF_MEM *p; 31 | BIO_get_mem_ptr(bio, &p); 32 | int n = p->length; 33 | char dst[n]; 34 | memcpy(dst, p->data, n); 35 | BIO_free_all(bio); 36 | 37 | lua_pushlstring(L, dst, n); 38 | return 1; 39 | } 40 | 41 | /** 42 | * BASE64解码 43 | * 44 | * LUA示例: 45 | * local codec = require('codec') 46 | * local base64str = [[...]] --BASE64字符串,无换行 47 | * local result = codec.base64_decode(base64str) 48 | */ 49 | static int codec_base64_decode(lua_State *L) 50 | { 51 | size_t len; 52 | const char *cs = luaL_checklstring(L, 1, &len); 53 | BIO *b64 = BIO_new(BIO_f_base64()); 54 | BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); 55 | BIO *bio = BIO_new_mem_buf((void *)cs, len); 56 | bio = BIO_push(b64, bio); 57 | char dst[len]; 58 | int n = BIO_read(bio, dst, len); 59 | BIO_free_all(bio); 60 | 61 | lua_pushlstring(L, dst, n); 62 | return 1; 63 | } 64 | 65 | /** 66 | * MD5编码 67 | * 68 | * LUA示例: 69 | * local codec = require('codec') 70 | * local src = [[...]] 71 | * local result = codec.md5_encode(src) 72 | */ 73 | static int codec_md5_encode(lua_State *L) 74 | { 75 | size_t len; 76 | const char *cs = luaL_checklstring(L, 1, &len); 77 | unsigned char bs[16]; 78 | char dst[32]; 79 | 80 | MD5((unsigned char *)cs, len, bs); 81 | 82 | int i; 83 | for(i = 0; i < 16; i++) 84 | sprintf(dst + i * 2, "%02x", bs[i]); 85 | 86 | lua_pushlstring(L, dst, 32); 87 | return 1; 88 | } 89 | 90 | /** 91 | * HMAC-SHA1编码 92 | * 93 | * LUA示例: 94 | * local codec = require('codec') 95 | * local src = [[...]] 96 | * local key = [[...]] 97 | * local result = codec.hmac_sha1_encode(src, key) 98 | */ 99 | static int codec_hmac_sha1_encode(lua_State *L) 100 | { 101 | size_t len, klen; 102 | const char *cs = luaL_checklstring(L, 1, &len); 103 | const char *key = luaL_checklstring(L, 2, &klen); 104 | unsigned char bs[EVP_MAX_MD_SIZE]; 105 | 106 | unsigned int n; 107 | const EVP_MD *evp = EVP_sha1(); 108 | HMAC(evp, key, klen, (unsigned char *)cs, len, bs, &n); 109 | 110 | int hexn = n * 2, i; 111 | char dst[hexn]; 112 | for(i = 0; i < n; i++) 113 | sprintf(dst + i * 2, "%02x", bs[i]); 114 | 115 | lua_pushlstring(L, dst, hexn); 116 | return 1; 117 | } 118 | 119 | /** 120 | * AES-ECB-PKCS5Padding加密 121 | * 122 | * LUA示例: 123 | * local codec = require('codec') 124 | * local src = 'something' 125 | * local key = [[...]] --16位数字串 126 | * local bs = codec.aes_encrypt(src, key) 127 | * local dst = codec.base64_encode(bs) --BASE64密文 128 | */ 129 | static int codec_aes_encrypt(lua_State *L) 130 | { 131 | size_t len; 132 | const char *src = luaL_checklstring(L, 1, &len); 133 | char *key = luaL_checkstring(L, 2); 134 | 135 | EVP_CIPHER_CTX ctx; 136 | EVP_CIPHER_CTX_init(&ctx); 137 | 138 | int ret = EVP_EncryptInit_ex(&ctx, EVP_aes_128_ecb(), NULL, (unsigned char *)key, NULL); 139 | if(ret != 1) 140 | { 141 | EVP_CIPHER_CTX_cleanup(&ctx); 142 | return luaL_error(L, "EVP encrypt init error"); 143 | } 144 | 145 | int dstn = len + 128, n, wn; 146 | char dst[dstn]; 147 | memset(dst, 0, dstn); 148 | 149 | ret = EVP_EncryptUpdate(&ctx, (unsigned char *)dst, &wn, (unsigned char *)src, len); 150 | if(ret != 1) 151 | { 152 | EVP_CIPHER_CTX_cleanup(&ctx); 153 | return luaL_error(L, "EVP encrypt update error"); 154 | } 155 | n = wn; 156 | 157 | ret = EVP_EncryptFinal_ex(&ctx, (unsigned char *)(dst + n), &wn); 158 | if(ret != 1) 159 | { 160 | EVP_CIPHER_CTX_cleanup(&ctx); 161 | return luaL_error(L, "EVP encrypt final error"); 162 | } 163 | EVP_CIPHER_CTX_cleanup(&ctx); 164 | n += wn; 165 | 166 | lua_pushlstring(L, dst, n); 167 | return 1; 168 | } 169 | 170 | /** 171 | * AES-ECB-PKCS5Padding解密 172 | * 173 | * LUA示例: 174 | * local codec = require('codec') 175 | * local src = [[...]] --BASE64密文 176 | * local key = [[...]] --16位数字串 177 | * local bs = codec.base64_decode(src) 178 | * local dst = codec.aes_decrypt(bs, key) 179 | */ 180 | static int codec_aes_decrypt(lua_State *L) 181 | { 182 | size_t len; 183 | const char *src = luaL_checklstring(L, 1, &len); 184 | char *key = luaL_checkstring(L, 2); 185 | 186 | EVP_CIPHER_CTX ctx; 187 | EVP_CIPHER_CTX_init(&ctx); 188 | 189 | int ret = EVP_DecryptInit_ex(&ctx, EVP_aes_128_ecb(), NULL, (unsigned char *)key, NULL); 190 | if(ret != 1) 191 | { 192 | EVP_CIPHER_CTX_cleanup(&ctx); 193 | return luaL_error(L, "EVP decrypt init error"); 194 | } 195 | 196 | int n, wn; 197 | char dst[len]; 198 | memset(dst, 0, len); 199 | 200 | ret = EVP_DecryptUpdate(&ctx, (unsigned char *)dst, &wn, (unsigned char *)src, len); 201 | if(ret != 1) 202 | { 203 | EVP_CIPHER_CTX_cleanup(&ctx); 204 | return luaL_error(L, "EVP decrypt update error"); 205 | } 206 | n = wn; 207 | 208 | ret = EVP_DecryptFinal_ex(&ctx, (unsigned char *)(dst + n), &wn); 209 | if(ret != 1) 210 | { 211 | EVP_CIPHER_CTX_cleanup(&ctx); 212 | return luaL_error(L, "EVP decrypt final error"); 213 | } 214 | EVP_CIPHER_CTX_cleanup(&ctx); 215 | n += wn; 216 | 217 | lua_pushlstring(L, dst, n); 218 | return 1; 219 | } 220 | 221 | /** 222 | * SHA1WithRSA私钥签名 223 | * 224 | * LUA示例: 225 | * local codec = require('codec') 226 | * local src = 'something' 227 | * local pem = [[...]] --私钥PEM字符串 228 | * local bs = codec.rsa_private_sign(src, pem) 229 | * local dst = codec.base64_encode(bs) --BASE64签名 230 | */ 231 | static int codec_rsa_private_sign(lua_State *L) 232 | { 233 | size_t len; 234 | const char *src = luaL_checklstring(L, 1, &len); 235 | char *pem = luaL_checkstring(L, 2); 236 | 237 | SHA_CTX c; 238 | unsigned char sha[SHA_DIGEST_LENGTH]; 239 | memset(sha, 0, SHA_DIGEST_LENGTH); 240 | if(SHA_Init(&c) != 1) 241 | { 242 | OPENSSL_cleanse(&c, sizeof(c)); 243 | return luaL_error(L, "SHA init error"); 244 | } 245 | if(SHA1_Update(&c, src, len) != 1) 246 | { 247 | OPENSSL_cleanse(&c, sizeof(c)); 248 | return luaL_error(L, "SHA update error"); 249 | } 250 | if(SHA1_Final(sha, &c) != 1) 251 | { 252 | OPENSSL_cleanse(&c, sizeof(c)); 253 | return luaL_error(L, "SHA update error"); 254 | } 255 | OPENSSL_cleanse(&c, sizeof(c)); 256 | 257 | BIO *bio = BIO_new_mem_buf((void *)pem, -1); 258 | if(bio == NULL) 259 | { 260 | BIO_free_all(bio); 261 | return luaL_error(L, "PEM error"); 262 | } 263 | RSA *rsa = PEM_read_bio_RSAPrivateKey(bio, NULL, NULL, NULL); 264 | if(rsa == NULL) 265 | { 266 | BIO_free_all(bio); 267 | return luaL_error(L, "RSA read private key error"); 268 | } 269 | BIO_free_all(bio); 270 | 271 | int n = RSA_size(rsa), wn; 272 | char dst[n]; 273 | memset(dst, 0, n); 274 | 275 | int ret = RSA_sign(NID_sha1, (unsigned char *)sha, SHA_DIGEST_LENGTH, (unsigned char *)dst, (unsigned int *)&wn, 276 | rsa); 277 | if(ret != 1) 278 | { 279 | RSA_free(rsa); 280 | BIO_free_all(bio); 281 | return luaL_error(L, "RSA sign error"); 282 | } 283 | RSA_free(rsa); 284 | 285 | lua_pushlstring(L, dst, wn); 286 | return 1; 287 | } 288 | 289 | /** 290 | * SHA1WithRSA公钥验签 291 | * 292 | * LUA示例: 293 | * local codec = require('codec') 294 | * local src = 'something' 295 | * local sign = [[...]] --BASE64签名 296 | * local bs = codec.base64_decode(sign) 297 | * local pem = [[...]] --公钥PEM字符串 298 | * local type = 1 299 | * local ok = codec.rsa_public_verify(src, bs, pem, type) --true/false 300 | */ 301 | static int codec_rsa_public_verify(lua_State *L) 302 | { 303 | size_t srclen, signlen; 304 | const char *src = luaL_checklstring(L, 1, &srclen); 305 | const char *sign = luaL_checklstring(L, 2, &signlen); 306 | char *pem = luaL_checkstring(L, 3); 307 | int type = luaL_checkint(L, 4); 308 | 309 | SHA_CTX ctx; 310 | int ctxlen = sizeof(ctx); 311 | unsigned char sha[SHA_DIGEST_LENGTH]; 312 | memset(sha, 0, SHA_DIGEST_LENGTH); 313 | if(SHA_Init(&ctx) != 1) 314 | { 315 | OPENSSL_cleanse(&ctx, ctxlen); 316 | return luaL_error(L, "SHA init error"); 317 | } 318 | if(SHA1_Update(&ctx, src, srclen) != 1) 319 | { 320 | OPENSSL_cleanse(&ctx, ctxlen); 321 | return luaL_error(L, "SHA update error"); 322 | } 323 | if(SHA1_Final(sha, &ctx) != 1) 324 | { 325 | OPENSSL_cleanse(&ctx, ctxlen); 326 | return luaL_error(L, "SHA update error"); 327 | } 328 | OPENSSL_cleanse(&ctx, ctxlen); 329 | 330 | BIO *bio = BIO_new_mem_buf((void *)pem, -1); 331 | if(bio == NULL) 332 | { 333 | BIO_free_all(bio); 334 | return luaL_error(L, "PEM error"); 335 | } 336 | RSA *rsa = type == 1 ? PEM_read_bio_RSAPublicKey(bio, NULL, NULL, NULL) : PEM_read_bio_RSA_PUBKEY(bio, NULL, NULL, NULL); 337 | if(rsa == NULL) 338 | { 339 | BIO_free_all(bio); 340 | return luaL_error(L, "RSA read public key error"); 341 | } 342 | BIO_free_all(bio); 343 | 344 | int ret = RSA_verify(NID_sha1, sha, SHA_DIGEST_LENGTH, (unsigned char *)sign, signlen, rsa); 345 | RSA_free(rsa); 346 | 347 | lua_pushboolean(L, ret); 348 | return 1; 349 | } 350 | 351 | /** 352 | * RSA公钥加密 353 | * 354 | * LUA示例: 355 | * local codec = require('codec') 356 | * local src = 'something' 357 | * local pem = [[...]] --公钥PEM字符串 358 | * local type = 1 359 | * local bs = codec.rsa_public_encrypt(src, pem, type) 360 | * local dst = codec.base64_encode(bs) --BASE64密文 361 | */ 362 | static int codec_rsa_public_encrypt(lua_State *L) 363 | { 364 | size_t len; 365 | const char *src = luaL_checklstring(L, 1, &len); 366 | char *pem = luaL_checkstring(L, 2); 367 | int type = luaL_checkint(L, 3); 368 | 369 | BIO *bio = BIO_new_mem_buf((void *)pem, -1); 370 | if(bio == NULL) 371 | { 372 | BIO_free_all(bio); 373 | return luaL_error(L, "PEM error"); 374 | } 375 | RSA *rsa = type == 1 ? PEM_read_bio_RSAPublicKey(bio, NULL, NULL, NULL) : PEM_read_bio_RSA_PUBKEY(bio, NULL, NULL, NULL); 376 | if(rsa == NULL) 377 | { 378 | BIO_free_all(bio); 379 | return luaL_error(L, "RSA read public key error"); 380 | } 381 | BIO_free_all(bio); 382 | 383 | int n = RSA_size(rsa); 384 | char dst[n]; 385 | memset(dst, 0, n); 386 | 387 | int ret = RSA_public_encrypt(len, (unsigned char *)src, (unsigned char *)dst, rsa, RSA_PKCS1_PADDING); 388 | if(ret != n) 389 | { 390 | RSA_free(rsa); 391 | BIO_free_all(bio); 392 | return luaL_error(L, "RSA public encrypt error"); 393 | } 394 | RSA_free(rsa); 395 | 396 | lua_pushlstring(L, dst, n); 397 | return 1; 398 | } 399 | 400 | /** 401 | * RSA私钥解密 402 | * 403 | * LUA示例: 404 | * local codec = require('codec') 405 | * local src = [[...]] --BASE64密文 406 | * local bs = codec.base64_decode(src) 407 | * local pem = [[...]] --私钥PEM字符串 408 | * local dst = codec.rsa_private_decrypt(bs, pem) 409 | */ 410 | static int codec_rsa_private_decrypt(lua_State *L) 411 | { 412 | const char *src = luaL_checkstring(L, 1); 413 | char *pem = luaL_checkstring(L, 2); 414 | 415 | BIO *bio = BIO_new_mem_buf((void *)pem, -1); 416 | if(bio == NULL) 417 | { 418 | BIO_free_all(bio); 419 | return luaL_error(L, "PEM error"); 420 | } 421 | RSA *rsa = PEM_read_bio_RSAPrivateKey(bio, NULL, NULL, NULL); 422 | if(rsa == NULL) 423 | { 424 | BIO_free_all(bio); 425 | return luaL_error(L, "RSA read private key error"); 426 | } 427 | BIO_free_all(bio); 428 | 429 | int n = RSA_size(rsa); 430 | char dst[n]; 431 | memset(dst, 0, n); 432 | 433 | int ret = RSA_private_decrypt(n, (unsigned char *)src, (unsigned char *)dst, rsa, RSA_PKCS1_PADDING); 434 | if(ret <= 0) 435 | { 436 | RSA_free(rsa); 437 | BIO_free_all(bio); 438 | return luaL_error(L, "RSA private decrypt error"); 439 | } 440 | RSA_free(rsa); 441 | 442 | lua_pushlstring(L, dst, ret); 443 | return 1; 444 | } 445 | 446 | static const struct luaL_Reg codec[] = 447 | { 448 | {"base64_encode", codec_base64_encode}, 449 | {"base64_decode", codec_base64_decode}, 450 | {"md5_encode", codec_md5_encode}, 451 | {"hmac_sha1_encode", codec_hmac_sha1_encode}, 452 | {"aes_encrypt", codec_aes_encrypt}, 453 | {"aes_decrypt", codec_aes_decrypt}, 454 | {"rsa_private_sign", codec_rsa_private_sign}, 455 | {"rsa_public_verify", codec_rsa_public_verify}, 456 | {"rsa_public_encrypt", codec_rsa_public_encrypt}, 457 | {"rsa_private_decrypt", codec_rsa_private_decrypt}, 458 | {NULL, NULL} 459 | }; 460 | 461 | int luaopen_codec(lua_State *L) 462 | { 463 | luaL_register(L, "codec", codec); 464 | return 1; 465 | } 466 | -------------------------------------------------------------------------------- /test/test.lua: -------------------------------------------------------------------------------- 1 | local codec = require('codec') 2 | 3 | for k, v in pairs(codec) do 4 | print(k, type(v)) 5 | end 6 | -------------------------------------------------------------------------------- /test/test_aes.lua: -------------------------------------------------------------------------------- 1 | local codec = require('codec') 2 | local src, key = '123456', '01234567890abcdef' 3 | local bs = codec.aes_encrypt(src, key) 4 | local dst = codec.base64_encode(bs) 5 | print(dst) 6 | 7 | local dbs = codec.base64_decode(dst) 8 | local dsrc = codec.aes_decrypt(dbs, key) 9 | print(dsrc) 10 | 11 | assert(dsrc == src) 12 | -------------------------------------------------------------------------------- /test/test_base64.lua: -------------------------------------------------------------------------------- 1 | local codec = require('codec') 2 | local src = '123456' 3 | local dst = codec.base64_encode(src) 4 | print(dst) 5 | local dsrc = codec.base64_decode(dst) 6 | print(dsrc) 7 | assert(dsrc == src) 8 | -------------------------------------------------------------------------------- /test/test_hmac_sha1.lua: -------------------------------------------------------------------------------- 1 | local codec = require('codec') 2 | local src, key = '123456', '112233' 3 | local dst = codec.md5_encode(src) 4 | print(dst) 5 | assert('06285a0e4a99a56f7f9d1e239acad4de7c79ebe9' == dst) 6 | -------------------------------------------------------------------------------- /test/test_md5.lua: -------------------------------------------------------------------------------- 1 | local codec = require('codec') 2 | local src = '123456' 3 | local dst = codec.md5_encode(src) 4 | print(dst) 5 | assert('e10adc3949ba59abbe56e057f20f883e' == dst) 6 | -------------------------------------------------------------------------------- /test/test_rsa_encrypt_decrypt.lua: -------------------------------------------------------------------------------- 1 | local codec = require('codec') 2 | local src = '123456' 3 | local pubpem = [[-----BEGIN PUBLIC KEY----- 4 | MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCsxjKD2lnmkmELoo5QphM/VdRE 5 | JKym26R0T+19JDa3MVZFDbwgUGT8XM8bElrKgxexhTVRt07btyIejdbiPx7sCbWc 6 | VP8peZI+QZEVVzaE2Ci5n0lP9v9GUSl0QfZU94uIwl++BVq0VFvbHax/R/q4oTRD 7 | 1u73ASM27QW42+cJFwIDAQAB 8 | -----END PUBLIC KEY-----]] 9 | local bs = codec.rsa_public_encrypt(src, pubpem, 2) 10 | local dst = codec.base64_encode(bs) 11 | print(dst) 12 | 13 | local privpem = [[-----BEGIN RSA PRIVATE KEY----- 14 | MIICXAIBAAKBgQCsxjKD2lnmkmELoo5QphM/VdREJKym26R0T+19JDa3MVZFDbwg 15 | UGT8XM8bElrKgxexhTVRt07btyIejdbiPx7sCbWcVP8peZI+QZEVVzaE2Ci5n0lP 16 | 9v9GUSl0QfZU94uIwl++BVq0VFvbHax/R/q4oTRD1u73ASM27QW42+cJFwIDAQAB 17 | AoGALHoNMQI52HBgSSV8q2hFVi2bKjuisoWibUrSIT/8UeaChd5GSq9Hf+vIaPit 18 | pKpgpBNdqX6d71PSlbj/01hadg5IxrGWQZWzT/3IzuhTxAu4TkztUJelGRcM6ykZ 19 | 5AxijiIxTLWSY/ygtEaM2QShhl8dCReNT+oIDGf/iMSTVykCQQDl07WZR9ATReVc 20 | vM7/v9iiz/g1Tj9/8AOuyYOZ5kp5a8IAr48dXixzuTZY66RwPj/J5vrzLuHc7Uc0 21 | RAi4hgmTAkEAwHMxP0KVOzDH49SsiUjfOycqrBl68QCXUWQj2mi7Bb1pLryoYDFv 22 | FTuk6pxKyfr5O8M2s8thTz6f3EO7hFqk7QJAdX8Ly2ZkYUYNoaDBbwzEk1AhhBcR 23 | 7bVmHJjXV/ndP0Aw+arHTutTbIJW35TxB5U7hVw6FdN1Ez6XdYgGsVeNUwJAEjlW 24 | SoVFmGtQInT7Oaza5sEYu19WUwgZTC3Nb1tHio2bLj/TOfi0ajBRt53BP0sy2sPr 25 | pC74MgbeIH+RfEERKQJBAIpPkQztkbpZwD9gDiK86U+HHYZrhglxgfDIXYwTH3z/ 26 | KCrfyNxiH2im9ZhwuhLs7LDD7wDPHUC5BItx2tYN10s= 27 | -----END RSA PRIVATE KEY-----]] 28 | local dbs = codec.base64_decode(dst) 29 | local dsrc = codec.rsa_private_decrypt(dbs, privpem) 30 | print(dsrc) 31 | 32 | assert(dsrc == src) 33 | 34 | -------------------------------------------------------------------------------- /test/test_rsa_sign_verify.lua: -------------------------------------------------------------------------------- 1 | local codec = require('codec') 2 | local src = '123456' 3 | local privpem = [[-----BEGIN RSA PRIVATE KEY----- 4 | MIICXAIBAAKBgQCsxjKD2lnmkmELoo5QphM/VdREJKym26R0T+19JDa3MVZFDbwg 5 | UGT8XM8bElrKgxexhTVRt07btyIejdbiPx7sCbWcVP8peZI+QZEVVzaE2Ci5n0lP 6 | 9v9GUSl0QfZU94uIwl++BVq0VFvbHax/R/q4oTRD1u73ASM27QW42+cJFwIDAQAB 7 | AoGALHoNMQI52HBgSSV8q2hFVi2bKjuisoWibUrSIT/8UeaChd5GSq9Hf+vIaPit 8 | pKpgpBNdqX6d71PSlbj/01hadg5IxrGWQZWzT/3IzuhTxAu4TkztUJelGRcM6ykZ 9 | 5AxijiIxTLWSY/ygtEaM2QShhl8dCReNT+oIDGf/iMSTVykCQQDl07WZR9ATReVc 10 | vM7/v9iiz/g1Tj9/8AOuyYOZ5kp5a8IAr48dXixzuTZY66RwPj/J5vrzLuHc7Uc0 11 | RAi4hgmTAkEAwHMxP0KVOzDH49SsiUjfOycqrBl68QCXUWQj2mi7Bb1pLryoYDFv 12 | FTuk6pxKyfr5O8M2s8thTz6f3EO7hFqk7QJAdX8Ly2ZkYUYNoaDBbwzEk1AhhBcR 13 | 7bVmHJjXV/ndP0Aw+arHTutTbIJW35TxB5U7hVw6FdN1Ez6XdYgGsVeNUwJAEjlW 14 | SoVFmGtQInT7Oaza5sEYu19WUwgZTC3Nb1tHio2bLj/TOfi0ajBRt53BP0sy2sPr 15 | pC74MgbeIH+RfEERKQJBAIpPkQztkbpZwD9gDiK86U+HHYZrhglxgfDIXYwTH3z/ 16 | KCrfyNxiH2im9ZhwuhLs7LDD7wDPHUC5BItx2tYN10s= 17 | -----END RSA PRIVATE KEY-----]] 18 | local bs = codec.rsa_private_sign(src, privpem) 19 | local sign = codec.base64_encode(bs) 20 | print(sign) 21 | 22 | local dbs = codec.base64_decode(sign) 23 | local pubpem = [[-----BEGIN PUBLIC KEY----- 24 | MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCsxjKD2lnmkmELoo5QphM/VdRE 25 | JKym26R0T+19JDa3MVZFDbwgUGT8XM8bElrKgxexhTVRt07btyIejdbiPx7sCbWc 26 | VP8peZI+QZEVVzaE2Ci5n0lP9v9GUSl0QfZU94uIwl++BVq0VFvbHax/R/q4oTRD 27 | 1u73ASM27QW42+cJFwIDAQAB 28 | -----END PUBLIC KEY-----]] 29 | local ok = codec.rsa_public_verify(src, dbs, pubpem, 2) 30 | assert(ok) 31 | --------------------------------------------------------------------------------