Electronic signature - algorithm

I was asked to code electronic signature for the form. But I can't understand a thing from the description. Is it my qualification or something is missing?
Here is description:
MAC008(x1, x2, …, xn) := RSA(SHA-1(p(x1)||x1||p(x2)||x2||…||p(xn)||xn),d,n)
where:
|| - symbol lines connecting
x1, x2, …, xn inquiry parameters;
p function that returns the parameter length. The result is provided as a three-segment number (e.g. 007)
d – RSA secret exponent
n- RSA module

Let's say that p1 is defined as returning "Hello \x1, how are you" so
p1(chris) = "Hello chris, how are you".
What this is asking you to do is turn
MAC008(chris) = RSA(SHA-1(Hello chris, how are youchris),SOMESECRET,someRSAmodule)
Into the modules "signature". Sha-1 is a hashing algorithm that turns a set of data into a pre determined length string, or hash. RSA is a signature algorithm that uses a public/private key encryption scheme. You freely make available the public key, and encrypt the hash with your private key. This provides no data security, but an individual with your public key can be positive that the data is from you, because this is the only way their public key would work on your data set.

Related

SM2 algorithm, the length of public key encryption is inconsistent with the expectation

The public key encrypts a 48Char data, and the result is arranged according to the format of C1C3C2.
C1
(randomly generating a point on the elliptic curve of SM2) and two BigInteger numbers of 32byte are generated, which is the first part of the SM2 encryption result, and 128Char is fixed.
C3
is the hash value, which is used to verify the data and is fixed at 64Char.
Now the fixed length(C1+C3) is 128+64=192Char.-
C2
is the real ciphertext, which is the encryption result of plaintext. Its length is 32Char, which is the same as that of plaintext.
So my encryption result should be 192+48=240Char.
Here is my calculation process.
public key:
d69625bdf33199474ea021ad261926683b2619acf15c1c285ff23b06e07bbddc78cf9361e971c2c43865397002830fd851f8d5d546e79b97d8479e6532f415d4
data:
egzjyuE5d4bts0yAVKRVfg==
24*2Char = 48Char
res:
04B415AED7CFD3E4A2857FD05AB54CD48993CBFB45B61BB192F1850BEBEA3F67B141DDD1FB986AD6EF246C02D1A7F8B018CC4236E221D51E2D68B91704CAB5CC16590127B9F1F3BBC72A856F3832A575F615FC0A4AE60F4D237B92F19EE30C6CA28A0F928DE7FE2D993829BF6CD5EDFFB2D994BFBE8E5114F5
I knew I needed to remove the starting 04, so the result became
res:
B415AED7CFD3E4A2857FD05AB54CD48993CBFB45B61BB192F1850BEBEA3F67B141DDD1FB986AD6EF246C02D1A7F8B018CC4236E221D51E2D68B91704CAB5CC16590127B9F1F3BBC72A856F3832A575F615FC0A4AE60F4D237B92F19EE30C6CA28A0F928DE7FE2D993829BF6CD5EDFFB2D994BFBE8E5114F5
Its length is 240
The partner gave me a reference result with a length of 224. I guess this length should be correct.
Here are their exact words.
Password plaintext 123456 Test data
Test environment public key:
d69625bdf33199474ea021ad261926683b2619acf15c1c285ff23b06e07bbddc78cf9361e971c2c43865397002830fd851f8d5d546e79b97d8479e6532f415d4
Random number encryption password plaintext:
egzjyuE5d4bts0yAVKRVfg==
Encrypted public key random number:
Here it is, with a length of 224.
5b00d62299e75c04c45a09303810b793787a2f2df1872253deee716b94a20fcaf64eb464ea322433ca48febca1f684ee5bf65ea1deb85b21b104ad6fbdc75a7bf1bb3a5cf75ab66cf1fe4ef ed3b6c0b512aaefc3bbb9132e65177233a77aaa93055c77334fdcd8a237b4faf15f8f0ae4
why??????

How does hashtable read correct values in case of collision?

I have some hashtable. For instance I have two entities like
john = { 1stname: jonh, 2ndname: johnson },
eric = { 1stname: eric, 2ndname: ericson }
Then I put them in hashtable:
ht["john"] = john;
ht["eric"] = eric;
Let's imagine there is a collision and hashtable use chaining to fix it. As a result there should be a linked list with these two entities like this
How does hashtable understand what entity should be returned for key? Hash values are the same and it knows nothing about entities structure. For instance if I write thisvar val = ht["john"]; how does hashtable (having only key value and its hash) find out that value should be john record and not eric.
I think what you are confused about is what is stored at each location in the hashtable's adjacent list. It seems like you assume that only the value is being stored. In fact, the data in each list node is a tuple (key, value).
Once you ask for ht['john'], the hashtable find the list associated with hash('john') and if the list is not empty it searches for the key 'john' in the list. If the key is found as the first element of the tuple then the value (second element of the tuple) is returned. If the key is not found, then it means that the element is not in the hashtable.
To summarize, the key hash is used to quickly identify the cell in which the element should be stored if present. Actual key equality is tested for to decide whether the key exists or not.
Is this what you are asking for? I have already put this in comments but seems to me you did not follow link
Collision Resolution in the Hashtable Class
Recall that when inserting an item into or retrieving an item from a hash table, a collision can occur. When inserting an item, an open slot must be found. When retrieving an item, the actual item must be found if it is not in the expected location. Earlier we briefly examined two collusion resolution strategies:
Linear probing
Quardratic probing
The Hashtable class uses a different technique referred to as rehasing. (Some sources refer to rehashing as double hashing.)
Rehasing works as follows: there is a set of hash different functions, H1 ... Hn, and when inserting or retrieving an item from the hash table, initially the H1 hash function is used. If this leads to a collision, H2 is tried instead, and onwards up to Hn if needed. The previous section showed only one hash function, which is the initial hash function (H1). The other hash functions are very similar to this function, only differentiating by a multiplicative factor. In general, the hash function Hk is defined as:
Hk(key) = [GetHash(key) + k * (1 + (((GetHash(key) >> 5) + 1) % (hashsize – 1)))] % hashsize
Mathematical Note With rehasing it is important that each slot in the hash table is visited exactly once when hashsize number of probes are made. That is, for a given key you don't want Hi and Hj to hash to the same slot in the hash table. With the rehashing formula used by the Hashtable class, this property is maintained if the result of (1 + (((GetHash(key) >> 5) + 1) % (hashsize – 1))and hashsize are relatively prime. (Two numbers are relatively prime if they share no common factors.) These two numbers are guaranteed to be relatively prime if hashsize is a prime number.
Rehasing provides better collision avoidance than either linear or quadratic probing.
sources here

how to encrypt and decrypt with AES CBC 128 in Elixir

I have an app in Rails with following methods to encrypt and decrypt a text and communicate with java clients.
def encrypt(string, key)
cipher = OpenSSL::Cipher::AES.new(128, :CBC)
cipher.encrypt
cipher.padding = 1
cipher.key = hex_to_bin(Digest::SHA1.hexdigest(key)[0..32])
cipher_text = cipher.update(string)
cipher_text << cipher.final
return bin_to_hex(cipher_text).upcase
end
def decrypt(encrypted, key)
encrypted = hex_to_bin(encrypted.downcase)
cipher = OpenSSL::Cipher::AES.new(128, :CBC)
cipher.decrypt
cipher.padding = 1
cipher.key = hex_to_bin(Digest::SHA1.hexdigest(key)[0..32])
d = cipher.update(encrypted)
d << cipher.final
rescue Exception => exc
end
def hex_to_bin(str)
[str].pack "H*"
end
def bin_to_hex(str)
str.unpack('C*').map{ |b| "%02X" % b }.join('')
end
I need do the same in Elixir for phoenix framework. Since I'm new to Elixir I couldn't find a way for that.
I Found that Elixir uses Erlang's :crypto Module for that. In documentations there was no method for AES CBC encryption.
The block_encrypt/4 function from the Erlang crypto module is the function you want. Unlike the Ruby OpenSSL bindings, the Erlang code doesn’t handle padding, so you will need to do that yourself before encrypting (and remove it after decrypting).
NOTE: As of Erlang v23, the block_encrypt/4 and block_decrypt/4 functions (and their /3 sisters) are deprecated and will be removed from the Erlang crypto module in Erlang v24. The new API functions that have replaced them are crypto_one_time/4 and crypto_one_time/5 and these functions should be used for all new Erlang/Elixir programs. The new API functions support IVs and other improvements over the old functions.
However, unless this is just a toy app for learning purposes, I would recommend not doing this kind of crypto stuff yourself if you can avoid it. Rather you should find a higher level API that takes care of the various details where you can go wrong. I have listed some potential issues with your code as it is below, as well as a suggestion of what to do instead.
The padding that OpenSSL uses (sometimes called PKCS7 padding) is fairly simple. First you need to work out how many bytes you need to add to your data to make the length into a multiple of the block size (16 for AES). Then you simply add that many bytes of that value to the end. For example if your data was 14 bytes long then you would need to add two bytes, and each of those bytes would have the value 0x02 (2 bytes each with value 2). Note that you always add padding, so if your data is already a multiple of 16 byte then you add another 16 bytes (all with value 0x10).
To strip the padding you simply look at the value of the last byte and remove that many bytes from the end (you should probably check that the padding is correct too, i.e. all the bytes have the expected value).
Here is a simple implementation in Elixir (there may be a better / clearer / more idiomatic way to do this):
# These will need to be in a module of course
def pad(data, block_size) do
to_add = block_size - rem(byte_size(data), block_size)
data <> to_string(:string.chars(to_add, to_add))
end
def unpad(data) do
to_remove = :binary.last(data)
:binary.part(data, 0, byte_size(data) - to_remove)
end
You can now use these along with the :crypto.block_encrypt function to get AES CBC encryption like your Ruby code:
# BAD, don't do this!
# This is just to reproduce your code, where you are not using
# an initialisation vector.
#zero_iv to_string(:string.chars(0, 16))
#aes_block_size 16
def encrypt(data, key) do
:crypto.block_encrypt(:aes_cbc128, key, #zero_iv, pad(data, #aes_block_size))
end
def decrypt(data, key) do
padded = :crypto.block_decrypt(:aes_cbc128, key, #zero_iv, data)
unpad(padded)
end
Some issues
Here are some potential problems with your code. This is not an exhaustive list, just some things I noticed (I am not an expert in crypto).
No authentication. Unless you’re checking the authentication in another method before the code you show, then you don’t have any authentication of the messages. This is very bad. You are exposing yourself to potential padding oracle attacks (where an attacker could decrypt the messages) and things like bit-flipping attacks, where an attacker can send specially modified messages that your code might not recognise as bad, and cause some undesired action to take place.
You should be using something like HMAC. But even if you decide to use a HMAC, there are still several questions you need to work out. Where does the HMAC key come from? Can we use the same key for encryption and authentication? Do we calculate the HMAC over the plaintext or the ciphertext? Should it cover the IV as well?
No Initialisation Vector. CBC mode should make use of an initialisation vector, or IV. In the Ruby OpenSSL bindings if you don’t specify one it just uses zero bytes (which is why we needed to create the #zero_iv in the code above. Each message should have its own IV. This can just be a random series of bytes, and doesn’t need to be kept secret (it can just be sent prepended to the ciphertext).
Weak key generation. I could be wrong with this one, but since you are calculating the SHA1 hash of the provided key argument to use as the encryption/decryption key it suggest that this argument is actually a password. If this is the case then you should be using a better key derivation function (and if not then what’s the purpose of the hashing?). If you are using an easy for a human to remember password (or a single hash of one) you could be vulnerable to brute force attacks where an attacker tries lots of dictionary words as the key.
You should be using a proper key derivation function, such as PBKDF2. Even then you will still have complications since you might need two keys (encryption and authentication), so you need to work out how to generate them both.
What to use instead
If possible you should look for a higher level library that takes into account these factors and provides a simpler API. I would recommend Libsodium, which has bindings for many languages including Ruby, Elixir, Erlang, and Java/Android.
I'd recommend not using CBC mode directly but use GCM mode as this will provide authentication as well.
In Elixir (for a 256bit AES key)
# Gen once (see also https://hexdocs.pm/plug/Plug.Crypto.KeyGenerator.html#content)
k = :crypto.strong_rand_bytes(32)
# Gen every time you encrypt a message
iv = :crypto.strong_rand_bytes(32)
{ct, tag} = :crypto.block_encrypt(:aes_gcm, k, iv, {"AES128GCM", msg})
payload = Base.encode16(iv <> tag <> ct)
To decrypt:
<<iv::binary-32, tag::binary-16, ct::binary>> = Base.decode16!(payload)
:crypto.block_decrypt(:aes_gcm, k, iv, {"AES128GCM", ct, tag})
Here is what I use for ECB, CBC should be the same with the added need to pass the previous block cipher in the accumulator. Don't forget that you also need to write a function to pad the term to 16 byte blocks(the ruby seems to do that automatically).
Key = "12345678"
AES_ECB_Encrypt =
fun Crypt(<<Block:16/binary, Rest/binary>>, Acc) ->
NewAcc = erlang:iolist_to_binary( [Acc, crypto:block_encrypt(aes_ecb, Key, Block)] ),
Crypt(Rest, NewAcc);
Crypt(_, Acc) ->
Acc
end,
AES_ECB_Encrypt(<<"hello00000000000">>, <<>>)
JOSE.JWA component from JOSE package has block_decrypt/4 and block_encrypt/4 functions.
iex> JOSE.JWA.crypto_supports()
[ciphers: [aes_cbc: 128, aes_cbc: 192, aes_cbc: 256, aes_ecb: 128, aes_ecb: 192,
aes_ecb: 256, aes_gcm: 128, aes_gcm: 192, aes_gcm: 256,
chacha20_poly1305: 256],
hashs: [:md5, :poly1305, :sha, :sha256, :sha384, :sha512, :shake256],
public_keys: [:ec_gf2m, :ecdh, :ecdsa, :ed25519, :ed25519ph, :ed448, :ed448ph,
:rsa, :x25519, :x448], rsa_crypt: [:rsa1_5, :rsa_oaep, :rsa_oaep_256],
rsa_sign: [:rsa_pkcs1_padding, :rsa_pkcs1_pss_padding]]
Thanks #matt, I wrote my AES_ECB in Elixir.
Hope that it helps you, CBC should be the same.
def encrypt(data, key) do
:crypto.block_encrypt(:aes_ecb, key, pad(data, #aes_block_size))
end
# PKCS5Padding
defp pad(data, block_size) do
to_add = block_size - rem(byte_size(data), block_size)
data <> :binary.copy(<<to_add>>, to_add)
end
def decrypt(data, key) do
padded = :crypto.block_decrypt(:aes_ecb, key, data)
unpad(padded)
end
defp unpad(data) do
to_remove = :binary.last(data)
:binary.part(data, 0, byte_size(data) - to_remove)
end

Why don't I need a 32 bit key, or initialization vector for NodeJS crypto?

I was working interchangeably with Node's crypto library and Ruby's OpenSSL library.
The challenge I was coming across was that I could encrypt usingaes256 in both libraries.
However, in node using the crypto.createDecipher('aes256', key) I could have a key that was less than 32 bits long, but ruby would throw an error saying the key is not long enough when using:
cipher = OpenSSL::Cipher.new 'aes256'
cipher.encrypt
key = 'geeses'
I also don't have to set an initialization vector for node, but ruby seems to set one under the covers. I'm pretty new to this crypto stuff, what's going on here?
While #mscdex answers is perfectly, I want to add how to get a cipher with a specific key when your algorithm does not require Initialization Vector using the crypto.createCipheriv or crypto.createDecipheriv
Taking the case of AES-256-ECB where chaining is not done and hence IV is not used.
You can pass empty Buffer as IV.
var data = "plaintext";
const key = crypto.randomBytes(32);
var iv = new Buffer('');
var cipher = crypto.createCipheriv('AES-256-ECB',key,iv);
var encrypted = cipher.update(data,'utf8','base64');
encrypted += cipheriv.final('base64');
console.log('encrypted AES-256-ECB',encrypted);
And decrypt fairly simply using the same pattern:
var decipheriv = crypto.createDecipheriv('AES-256-ECB',key,iv);
var decryptediv = decipheriv.update(encrypted,'base64','utf8');
decryptediv += decipheriv.final('utf8');
console.log('decrypted base64 aes-256 ',decryptediv);
When you use crypto.createDecipher(), the value you pass as the second argument is a password from which a key and IV will be derived (using one iteration of MD5 hashing). This is accomplished by using EVP_BytesToKey() to create those two values. OpenSSL knows the correct lengths both values need to be because the cipher is also passed to EVP_BytesToKey().
So most likely the Ruby function is more analogous to node's crypto.createDecipheriv() which accepts both a key and an IV (which need to be the right lengths for the cipher).

RSA Decryption from Public Key Values

I'm a little stuck trying to figure out how to decrypt some messages and could use some hints as to what I may be doing wrong.
I was given a series of integer values that make up my cipher text. Here are just a few of them:
6584 15650 16198 11003
I was given the following public key
b = 3001
n = 18209
So to encrypt a message M, you would use the formula:
C = M^3001 mod 18209
I understand to encrypt, I need to find a 'd' value that satisfies:
bd = 1 mod 18209
3001d = 1 mod 18209
Any hints on a technique or algorithm to help me find a suitable value for 'd'?
EDIT: I figured it out! I'll come back and post the answer in a week or two as I'm sure my professor wouldn't be too pleased if I posted it here on public domain while my peers continue to work on it.

Resources