├── 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 |
--------------------------------------------------------------------------------