LUA HMAC Generation issue in 5.1 version - lua

I have an issue while I am creating the HMAC in LUA 5.1 version and same code is working in node.js
Node.js Code :
crypto.createHmac(
CONSTANTS.HMAC_ALORITHM_SHA,
Buffer.from(
secretAccessKey,
CONSTANTS.BASE64_ENCODING
)
).update(
Buffer.from(
stringToSign,
CONSTANTS.UTF8
)
).digest(
CONSTANTS.BASE64_ENCODING
);
I wanted to write in the same code LUa 5.1.

local sha2 = require("sha2")
local your_hmac_as_hex_string = sha2.hmac(
sha2.sha1, -- SHA-1
"secretAccessKey as binary string",
"stringToSign"
)
local your_hmac_as_binary_string = sha2.hex2bin(your_hmac_as_hex_string)
The library is here
UPDATE:
If your key is stored as base64, you need to convert it from base64 to binary:
local binary_key = sha2.base642bin(base64_key)
-- invoke sha2.hmac() here
And if you want to convert the result to base64:
local your_hmac_as_base64 = sha2.bin2base64(your_hmac_as_binary_string)

Related

Using io.tmpfile() with shell command, ran via io.popen, in Lua?

I'm using Lua in Scite on Windows, but hopefully this is a general Lua question.
Let's say I want to write a temporary string content to a temporary file in Lua - which I want to be eventually read by another program, - and I tried using io.tmpfile():
mytmpfile = assert( io.tmpfile() )
mytmpfile:write( MYTMPTEXT )
mytmpfile:seek("set", 0) -- back to start
print("mytmpfile" .. mytmpfile .. "<<<")
mytmpfile:close()
I like io.tmpfile() because it is noted in https://www.lua.org/pil/21.3.html :
The tmpfile function returns a handle for a temporary file, open in read/write mode. That file is automatically removed (deleted) when your program ends.
However, when I try to print mytmpfile, I get:
C:\Users\ME/sciteLuaFunctions.lua:956: attempt to concatenate a FILE* value (global 'mytmpfile')
>Lua: error occurred while processing command
I got the explanation for that here Re: path for io.tmpfile() ?:
how do I get the path used to generate the temp file created by io.tmpfile()
You can't. The whole point of tmpfile is to give you a file handle without
giving you the file name to avoid race conditions.
And indeed, on some OSes, the file has no name.
So, it will not be possible for me to use the filename of the tmpfile in a command line that should be ran by the OS, as in:
f = io.popen("python myprog.py " .. mytmpfile)
So my questions are:
Would it be somehow possible to specify this tmpfile file handle as the input argument for the externally ran program/script, say in io.popen - instead of using the (non-existing) tmpfile filename?
If above is not possible, what is the next best option (in terms of not having to maintain it, i.e. not having to remember to delete the file) for opening a temporary file in Lua?
You can get a temp filename with os.tmpname.
local n = os.tmpname()
local f = io.open(n, 'w+b')
f:write(....)
f:close()
os.remove(n)
If your purpose is sending some data to a python script, you can also use 'w' mode in popen.
--lua
local f = io.popen(prog, 'w')
f:write(....)
#python
import sys
data = sys.stdin.readline()

Reading text file in Lua using Luacom and ADODB: error

I am constructing a general purpose function to read a text file, which may be Ascii, UTF-8 or UTF-16. (The encoding is known when the function is invoked). The file name may contain UTF8 characters, so the standard lua io functions are not a solution. I have no control over the Lua implementation (5.3) or the binary modules available in the environment.
My current code is:
require "luacom"
local function readTextFile(sPath, bUnicode, iBits)
local fso = luacom.CreateObject("Scripting.FileSystemObject")
if not fso:FileExists(sPath) then return false, "" end --check the file exists
local so = luacom.CreateObject("ADODB.Stream")
--so.CharSet defaults to Unicode aka utf-16
--so.Type defaults to text
so.Mode = 1 --adModeRead
if not bUnicode then
so.CharSet = "ascii"
elseif iBits == 8 then
so.CharSet = "utf-8"
end
so:Open()
so:LoadFromFile(sPath)
local contents = so:ReadText()
so:Close()
return true, contents
end
--test Unicode(utf-16) files
local file = "D:\\OneDrive\\Desktop\\utf16.txt" --this exists
local booOK, factsetcontents = readTextFile(file, true, 16)
When executed I get the error: COM exception:(d:\my\lua\luacom-master\src\library\tluacom.cpp,382):Operation is not allowed in this context on line 19 [local stream = so:LoadFromFile(sPath)]
I've pored over the ADO documentation and am obviously missing something that is staring me in the face! Is what I'm trying to do impossible?
ETA: If I comment out the line so.Mode = 1, this works. Which is great, but I don't understand why, which meaans I may end up making the same mistake unwittingly, whatever that mistake is!
I don't know about AdoDB Stream.Mode and why the function failed. But I think it's rather tricky to use a ADODB COM object on Windows to read ASCII/UTF8/UNICODE encoded files.
You can instead :
use standard Lua io.open function in binary mode and use manual decoding of the bytes content
use a binary module to do all the work
use a specific Lua implementation for Windows that can read/write those kind of encoded files natively, like LuaRT

iOS swift3 equivalent of "RSA/NONE/OAEPWithSHA256AndMGF1Padding"

I am getting decryption error on sever when I used SwiftyRSA to encrypt a text using publicKey on client.
I have referred this
RSA: encrypt in iOS, decrypt in Java but this is for SHA1.
I am using https://github.com/TakeScoop/SwiftyRSA library.
kSecPaddingOAEP and RSA/NONE/OAEPWithSHA1AndMGF1Padding works. But how Can I make it work for RSA/NONE/OAEPWithSHA256AndMGF1Padding
let str = "Clear Text"
let clear = try ClearMessage(string: str, using: .utf8)
let encrypted = try clear.encrypted(with: publicKey, padding: .OAEP)
I want to encrypt data in swift3 without touching server code.
As far as I know, Apple's security framework, it does not support OAEP padding with a SHA256 hash digest, but it can be done through the OpenSSL library.
https://github.com/x2on/OpenSSL-for-iPhone

Convert Binary Data to Torch Tensor in Lua

I have Lua code that downloads an image from a url using a luasocket:
local http = require('socket.http')
local image = require('image')
image_url = 'https://www.somedomain.com/someimage.jpg'
local body, code = http.request(image_url) -- body has jpg binary data
if not body then error(code) end -- check for errors
In order to read this image into a Torch tensor, I save it in a jpg file and read it using image.load:
-- open a file in binary mode to store the image
local f = assert(io.open('./temp.jpg', 'wb'))
f:write(body)
f:close()
tensor = image.load('temp.jpg')
Is there a way to convert the binary jpg data to a torch tensor directly without doing a write-to-and-read-from the hard-drive? Something like:
tensor = CovertBinaryDataToTorchTensor(body)
Thank you!
See image.decompressJPG.
You just have to pack your body string inside a ByteTensor first. This can be done by constructing this tensor with a storage which can set his contents with string(str).
One potential solution is to use graphicsmagick.
local gm = require 'graphicsmagick'
local img = gm.Image()
local ok = pcall(img.fromString, img, body)
img = img:toTensor('float', 'RGB', 'DHW')
I found this example in https://github.com/clementfarabet/graphicsmagick/blob/master/test/corrupt.lua and I know that
local body, code = http.request(image_url)
will return body as a string. And, obviously if pcall returns false, the image was corrupt.

Decrypting AES-256-CBC in Objective C

I am building an iPhone app which gets a decrypted string via JSON from a PHP backend.
In PHP I am encrypting the string like this:
$encrypt_method = "AES-256-CBC";
$secret_key = 'This is my secret key';
$secret_iv = 'This is my secret iv';
// hash
$key = hash('sha256', $secret_key);
// iv - encrypt method AES-256-CBC expects 16 bytes - else you will get a warning
$iv = substr(hash('sha256', $secret_iv), 0, 16);
if( $action == 'encrypt' ) {
$output = openssl_encrypt($string, $encrypt_method, $key, 0, $iv);
$output = base64_encode($output);
}
In Objective C I tried to decrypt this string with BBEAS: https://github.com/benoitsan/BBAES
This is the code I have got in Objective C:
NSData* salt = [BBAES IVFromString:#"This is my secret iv"];
NSData *key = [BBAES keyBySaltingPassword:#"This is my secret key" salt:salt keySize:BBAESKeySize256 numberOfIterations:BBAESPBKDF2DefaultIterationsCount];
NSData *decryptedMessage = [BBAES decryptedDataFromString:#"RlVnd01XOE5teTNseDFGQ3JScVhkQT09" IV:salt key:key];
NSLog(#"Decrypted message: %#", decryptedMessage);
The log only shows a null object now.
I have found a duplicate post for C#: How to decrypt an AES-256-CBC encrypted string
EDIT:
Lets say that i can adjust the encoding in PHP. How should I encrypt the string in PHP to be decrypted in Objective C?
You are not doing the same thing in PHP as in iOS. I am not familiar with this BBAES framework, but what you seem to have is a password from which you are generating a 256 bit AES key using PBKDF key derivation, and using that to decrypt the data.
However, in PHP you are hashing your password and using it to encrypt your data, so you are probably using different AES keys for encryption and decryption. And I am not sure that IVs match either.
What you should do is:
In PHP, generate a random 16 byte IV for every encryption you do and use PBKDF key derivation to generate the 256 bit AES key from your password. Keep in mind that the salt and the number of iterations have to be the same in both PHP and iOS. After the encryption, append the IV to the encrypted data and send it.
In iOS, extract the IV from the received ciphertext (the last 16 bytes), generate the AES key from your password the same way you did before using the same salt and number of iterations, and decrypt the data (without the 16 byte IV at the end)
Edit:
As #Zaph pointed out, I forgot to mention that you should use also the same type of padding. BBAES seem to use PKCS7 padding.
To decrypt in Objective C you can use Apples's version of the CommonCrypto C library. It has a man page and there are already several posts that show decryption examples on Stack Overflow for example:
Determine if key is incorrect with CCCrypt kCCOptionPKCS7Padding-Objective C
which comes from the tutorial here:
http://robnapier.net/aes-commoncrypto
This also really helped me:
CCCrypt decrypting in AES CBC works even without IV
If you have trouble getting it working post some code.

Resources