Erlang has a crypto function which generates public private keys (documentation copied below). However the documentation seems vague and I can't find any example code that describes how to generate the shared prime number or the generator. Can someone post an example that generates a public/private key pair? Thanks in advance for any help!
dh_generate_key(DHParams) -> {PublicKey,PrivateKey}
dh_generate_key(PrivateKey, DHParams) -> {PublicKey,PrivateKey}
Types:
DHParameters = [P, G]
P, G = Mpint
Where P is the shared prime number and G is the shared generator.
PublicKey, PrivateKey = Mpint()
Generates a Diffie-Hellman PublicKey and PrivateKey (if not given).
You don't generate the shared prime number or the generator for Diffie-Hellman. See:
http://en.wikipedia.org/wiki/Diffie-Hellman_key_exchange
The parameters P and G are agreed to ahead of time by both sides. Using the notation of the Wikipedia article, crypto:dh_generate_key is used for steps 2 & 3 to generate a/A & b/B, and then crypto:dh_compute_key is used for steps 4 & 5 to compute the shared secret s.
For RSA, I don't know of a standard library function that generates a public/private key pair. Generating primes is a fairly involved algorithm from what I remember; I would strongly recommend you not try to code it yourself. Diffie-Hellman key pairs are not suitable for use with RSA; they are different algorithms intended for different purposes.
Generally you don't need to generate these at runtime since you can reuse the key pair. You can use any number of other sources to actually generate it. (Maybe ssh-keygen would work? And there's always OpenSSL.) To use the key pair you've created, you'd use the crypto:rsa_ public/private _ encrypt/decrypt functions.
See cutkey (https://github.com/yrashk/cutkey)
"cutkey is an Erlang app for generating RSA keys. It is implemented as
a port driver that calls OpenSSL's RSA_generate_key on a thread from
the async pool."
os:command("openssl genpkey -algorithm RSA -out private_key.pem -pkeyopt rsa_keygen_bits:2048").
You can use the crypto:generate_key/2 function to create RSA public and private keys:
For a 2048 length
{Pub, Priv} = crypto:generate_key(rsa, {2048,65537}).
Or for a 1024 length
{Pub, Priv} = crypto:generate_key(rsa, {1024,65537}).
See: https://erlang.org/doc/apps/crypto/crypto.pdf (page 37)
generate_key(Type, Params) -> {PublicKey, PrivKeyOut}
Where
Type = rsa
Params = rsa_params() =
{ModulusSizeInBits :: integer(),
PublicExponent :: key_integer()}
Related
Am trying to send data to an external api that expects encrypted data using 3DES encryption but am having issues understanding how to pass my api key as the key field to erlangs des_ede3 cipher.
According to erlangs cipher docs des_ede3 expects 3 keys that are all 8 bytes in length. How can i pass my 24 byte api key as the key to elixir/erlang :cryptoblock_encrypt/4 function
*** how can i pass key to block_encrypt/4 ***
key = "123456789012345678901234"
data = "hello world! The world is yours"
block_size = 8
cipher = :crypto.block_encrypt(:des_ede3, [key, key, key], iv, pad(data, block_size))
How do i pass my 24 byte api key as the key to erlangs block_encrypt/4 in order for me to pass data to the external api.
Thanks
Use binary pattern matching:
<<k1 :: binary-size(8),
k2 :: binary-size(8),
k3 :: binary-size(8)>> = "123456789012345678901234"
#⇒ "123456789012345678901234"
{k1, k2, k3}
#⇒ {"12345678", "90123456", "78901234"}
I'm trying to use SecKeyRawSign on swift to digitally sign a String using SHA256withRSA. I can properly generate the RSA keys, but I'm not sure about what data to send to this function.
My goal is to use PKCS1 v1.5 format, which should generate the same signature as long as the private key and content to be signed are the same, i.e., there's no random component in the algorithm.
Also, I (think I) know that the algorith that I should first calculate the SHA256 hash of the message, then I should add a ASN.1 prefix describing the algorithm. And finally I should add the PKCS1 padding (0x00 0x01 0xff .. 0xff 0x00) to complete a 128-byte sequence for a 1024-bit key.
I tried passing the following combinations of data and padding to the function:
* message with PKCS1HSA256 padding
* sha256(message) with PKCS1HSA256 padding
* algorithm identifier + sha256(message) with PKCS1 padding
* pkcs1 padding + algorithm identifier + sha256(message) with raw padding
In each case the function returns no error, but each time I call the function with the same key and data, a different signature is generated.
Knowing that the algorithm has no random component, shouldn't I be getting the same signature every time?
So can somebody help me by letting me know what should be passed into each parameter to accomplish my goal? How data param should be constructed?
Thanks.
I know RSA private key contains the information of the associated public key. How can I dump the public key from the private key? I want to do it in iOS environment without openssl. Is it possible?
yes it is possible ...
but you have to handle all the stuff about the way how the key is represented, i.e. how the specific parts of the key are stored in a file, etc
your private key consists of some numbers, usually like this:
d (private exponent), N (common modulus) P,Q (two very large primes) dP and dQ (intermediate values for a computational shortcut ... ignore them for your task)
what you want to do is to calculate PHI = (P-1)*(Q-1) and then run the extended euclidean algorithm (see wikipedia for that) for d and PHI to find the multiplicative inverse element of d mod PHI ... this element is e (public exponent)
your public key then is the tuple (e, N)
Problem Description:
I need to build a regular expression / pattern to find a value that can either be decimal or hex
Background Information:
I am trying to build a lua function that will lookup a cert in index.txt and return the serial number. Ultimately, I need to be able to take the full cert name and run the following command:
openssl x509 -noout -in
/etc/ssl/cert/myusername.6A756C65654063616E2E77746274732E6E6574.8F.crt
-dates
I have the logic to build the file name, all the way up to the serial number... which in the above example, is 8F.
Here's what the index.txt file looks like:
R 140320154649Z 150325040807Z 8E unknown /CN=test#gmail.com/emailAddress=test#gmail.com
V 160324050821Z 8F unknown /CN=test#yahoo.com/emailAddress=test#yahoo.com
V 160324051723Z 90 unknown /CN=test2#yahoo.com/emailAddress=test2#yahoo.com
The serial number is field 4 in the first record, and field 3 in the rest of the records.
According to the documentation https://www.openssl.org/docs/apps/x509.html, serial number can either be hex or decimal.
I'm not quite sure yet how / who determines whether it's hex or decimal (i'm modifying someone else's code that uses openssl)... but I'm wondering if there's a way to check for both. I'll only be checking the value for records that are not Revoked ...aka. ones that do not have "R" in the first column.
Thanks.
Lua unfortunately does not support grouping of patterns, so that you could make the pattern for the second timestamp optional. What you could do is check for the two-timestamp pattern first, and if no match was found (which means that match returns nil), repeat for the one-timestamp pattern:
sn = string.match(line, "^%a%s+%d+Z%s+%d+Z%s+(%x+)")
if not sn then
sn = string.match(line, "^%a%s+%d+Z%s+(%x+)")
end
Note that you could do this all in one line if you're eager:
sn = string.match(line, "^%a%s+%d+Z%s+%d+Z%s+(%x+)") or string.match(line, "^%a%s+%d+Z%s+(%x+)")
Each set of parentheses captures what is matched inside and adds a return value. For more information on patterns in Lua, see the reference manual.
local cert = {
'R 140320154649Z 150325040807Z 8E unknown /CN=test#gmail.com/emailAddress=test#gmail.com',
'V 160324050821Z 8F unknown /CN=test#yahoo.com/emailAddress=test#yahoo.com',
'V 160324051723Z 90 unknown /CN=test2#yahoo.com/emailAddress=test2#yahoo.com'
}
-- for Lua 5.1
for _, crt in ipairs(cert) do
local n3, n4 = crt:match'^%S+%s+%S+%s+(%S+)%s+(%S+)'
local serial = n3:match'^%x+$' or n4:match'^%x+$'
print(serial)
end
-- for Lua 5.2
for _, crt in ipairs(cert) do
local serial = crt:match'^%S+%s+%S+.-%f[%S](%x+)%f[%s]'
print(serial)
end
I'm trying to extract a 1024-bit RSA public key from an already generated key pair (two SecKeyRefs), in order to send it over the wire. All I need is a plain (modulus, exponent) pair, which should take up exactly 131 bytes (128 for the modulus and 3 for the exponent).
However, when I fetch the key info as a NSData object, I get 140 bits instead of 131. Here's an example result:
<30818902 818100d7 514f320d eacf48e1 eb64d8f9 4d212f77 10dd3b48 ba38c5a6
ed6ba693 35bb97f5 a53163eb b403727b 91c34fc8 cba51239 3ab04f97 dab37736
0377cdc3 417f68eb 9e351239 47c1f98f f4274e05 0d5ce1e9 e2071d1b 69a7cac4
4e258765 6c249077 dba22ae6 fc55f0cf 834f260a 14ac2e9f 070d17aa 1edd8db1
0cd7fd4c c2f0d302 03010001>
After retrying the key generation a couple of times and comparing the resulting NSData objects, the bytes that remain the same for all keys are the first 7:
<30818902 818100>
The last three bytes look like the exponent (65537, a common value). There are also two bytes between the "modulus" and the exponent:
<0203>
Can someone with more crypto experience help me identify what encoding is this? DER? How do I properly decode the modulus and exponent?
I tried manually stripping out the modulus and exponent using
NSData* modulus = [keyBits subdataWithRange:(NSRange){ 7, 128 }];
NSData* exponent = [keyBits subdataWithRange:(NSRange){ 7 + 128 + 2, 3 }];
but I get errors when trying to decrypt data which the remote host encoded using that "key".
EDIT:
Here's a gist of the solution I ended up using to unpack the RSA blob: https://gist.github.com/vl4dimir/6079882
Assuming you want the solution to work under iOS, please have a look at this thread. The post confirms that the encoding is DER and shows how to extract the exponent and modulus from the NSData object you started with.
There is another solution that won't work on iOS, but will work on Desktop systems (including MacOS X) that have OpenSSL installed in this thread. Even if you are looking for the iOS-only solution you can still use this to verify your code is working correctly.