computing the exchange hash for ecdsa-sha2-nistp256 - ssh

I am writing code for an SSH server and can not get past the Elliptic Curve Diffie-Hellman Key Exchange Reply part of the connection. The client also closes the connection and says "Host Key does not match the signature supplied".
I am using putty as the client and a PIC micro-controller is running the server code.
From RFC 5656 [SSH ECC Algorithm Integration] :
"The hash H is formed by applying the algorithm HASH on a
concatenation of the following:
string V_C, client's identification string (CR and LF excluded)
string V_S, server's identification string (CR and LF excluded)
string I_C, payload of the client's SSH_MSG_KEXINIT
string I_S, payload of the server's SSH_MSG_KEXINIT
string K_S, server's public host key
string Q_C, client's ephemeral public key octet string
string Q_S, server's ephemeral public key octet string
mpint K, shared secret
"
the host key algorithm and key exchange algorithm is ecdsa-sha2-nistp256 and ecdh-sha2-nistp256 respectively.
referring to RFC 4251 for data type representations, as well as the source code in openSHH (openBSD) this is what I have concatenated.
4 bytes for then length of V_C followed by V_C
4 bytes for then length of V_S followed by V_S
4 bytes for length of I_C followed by I_C (payload is from Message Code to the start of Random Padding)
4 bytes for length of I_S followed by I_S (payload is from Message Code to the start of Random Padding)
4 bytes for the length of K_S followed by K_S (for K_S I used the same group of bytes that is used to calculate the fingerprint)
4 bytes for the length of Q_C followed by Q_C (i used the uncompressed string which has length of 65 - 04||X-coordinate||Y-coordinate)
4 bytes for the length of Q_S followed by Q_S
4 bytes for the length of K followed by K (length is 32 or 33 depending is the leading bit is set or not. If it is set then K is preceded by a 00 byte)
Once concatenated I hash it with SHA256 because I'm using NISTP256. SHA256 outputs 32 bytes which is the size of the curve, so I take the whole SHA256 output and perform the signature algorithm on it.
I can never get the correct signature from my message concatenation.
I know my signature algorithm is correct because given the message hash output I can get the correct signature.
I know my shared secret is correct because I get the same output as online shared secret calculators.
I know the SHA256 is correct because I get the same result using online calculators.
This leads me to assume the error is in the concatenation of the exchange hash.
Any help is greatly appreciated, thanks.

ECDSA signature generation is non-deterministic, i.e. part of the input is the hash and part of the input consists of random bytes. So whatever you do, you will always get a different signature. This is all right because signature verification will still work.
The only way to get a repeated signature is to mess with the random number generator (during testing, you don't want to sign two values using the same random number: you'd expose the private key!).

Related

Getting public key from DNSKEY RR public key field using Python

I am trying to parse and validate DNSSEC responses without using any DNS specific libraries. I am able to get the hexstring representation of a RSA key from the public key field value present in the DNSKEY RRs. According to RFC 8017, the RSA public key is represented with the ASN.1 type RSAPublicKey format which has a modulus and exponent. However, it doesn't specify anything more.
The hexstring(same as in Wireshark) is
"03010001ac1f62b7f85d62c550211fd70ddbbca7326cde13dca235f26f76a5dd5872db601d775ecd189955ed96e749fd8e8e6af3e133e8a8eb8b8afc25730c6318f949de9436fde6ea280b5ccbc09a43ee357617905690fdc09cda06bc5ad3bcd1bc4e43de9a4769ff83453e96a74642b23daabae00398539cfca56b04c200776c4841724cb09674b519eb7e3506a3e08e4f96b5a733425a1c55eecb1613552c022b246b27141652d907cdbc6e30b5f3341a1ba5dfbb503edddbd01e85f1c4206642cfb312e14f2772fe8b66143ba847382e95fb86ba215342ae9cca803655bccadef1123e06f3cf1626840e11200b1acda118c50805c6eacfd271d930b93f2e332d9521"
I saw other similar posts and tried to follow the solutions. Most of the solutions try to get it from a pem file or binary data or base64 encoded form. When I try to convert the hex to those forms and use the solution, I get errors like 'RSA key format not supported' etc..
Is there anyway I can get the public key from the hex? I would really appreciate any inputs! Thanks!
I finally managed to find the solution.
According to RFC 3110 section 2, we can split the given value into exponent length, exponent and modulus. I split them as specified and converted the hexadecimal to integer. The text from RFC is below
The structure of the algorithm specific portion
of the RDATA part of such RRs is as shown below.
Field Size
----- ----
exponent length 1 or 3 octets (see text)
exponent as specified by length field
modulus remaining space
For interoperability, the exponent and modulus are each limited to
4096 bits in length. The public key exponent is a variable length
unsigned integer. Its length in octets is represented as one octet
if it is in the range of 1 to 255 and by a zero octet followed by a
two octet unsigned length if it is longer than 255 bytes. The public
key modulus field is a multiprecision unsigned integer. The length
of the modulus can be determined from the RDLENGTH and the preceding
RDATA fields including the exponent.

How do I find password related information of a password protected PDF?

I was trying to gather information about password used to protect a PDF. I used PeePDF and xxd editor to view all the objects of password protected PDF.I came to know password info is stored in trailer part of PDF structure.When I run this command , I got
xxd my_encrypted.pdf | tail -n 4
00022c60: 5d0a 2f49 6e66 6f20 3220 3020 520a 2f45 ]./Info 2 0 R./E
00022c70: 6e63 7279 7074 2034 2030 2052 0a3e 3e0a ncrypt 4 0 R.>>.
00022c80: 7374 6172 7478 7265 660a 3134 3139 3934 startxref.141994
00022c90: 0a25 2545 4f46 0a .%%EOF.
So, I understood that /Encrypt dictionary is in object 4. Now using PeePDF, I tried
PPDF> object 4
<< /O ��%�}�&��
v����o
B��z���B�
/Filter /Standard
/Length 128
/V 2
/U ZM����S��3�
fmL
/R 3
/P -1 >>
/O is owner password
/U is user password of PDF
PPDF> info 4
Offset: 699
Size: 206
MD5: 8a74ac53f9e6c1f4da44bcdbb65509e9
Object: dictionary
References: []
I got this info . I didn't even get the hash of password. What is that junk text represent ? Is it encrypted password ? What is MD5 hash represent ?
please tell me if there are any other tools that could analyse PDFs and get hash of password that is protecting PDF.
Thank you
If nothing else helps, read the specification.
In the case at hand the specification to read is the PDF specification, i.e. ISO 32000-1 and ISO 32000-2.
A copy of ISO 32000-1 is published by Adobe at https://www.adobe.com/go/pdfreference/ (beware, the exact location has moved around a bit over the years) - it is complete and merely has the official ISO headers replaced by Adobe headers. Read section 7.6 Encryption therein.
In case of your PDF the encryption dictionary entry V with value 2 indicates the use of "Algorithm 1: Encryption of data using the RC4 or AES algorithms" in 7.6.2, "General Encryption Algorithm," but permitting encryption key lengths greater than 40 bits. The entry R with value 3 indicates the revision of the standard security handler. This algorithm/handler pair already is explained in ISO 32000-1.
In particular you can read there how the O and U values are calculated:
Algorithm 3: Computing the encryption dictionary’s O (owner password) value
a)Pad or truncate the owner password string as described in step (a) of "Algorithm 2: Computing an encryption key". If there is no owner password, use the user password instead.
b)Initialize the MD5 hash function and pass the result of step (a) as input to this function.
c)(Security handlers of revision 3 or greater) Do the following 50 times: Take the output from the previous MD5 hash and pass it as input into a new MD5 hash.
d)Create an RC4 encryption key using the first n bytes of the output from the final MD5 hash, where n shall always be 5 for security handlers of revision 2 but, for security handlers of revision 3 or greater, shall depend on the value of the encryption dictionary’s Length entry.
e)Pad or truncate the user password string as described in step (a) of "Algorithm 2: Computing an encryption key".
f)Encrypt the result of step (e), using an RC4 encryption function with the encryption key obtained in step (d).
g)(Security handlers of revision 3 or greater) Do the following 19 times: Take the output from the previous invocation of the RC4 function and pass it as input to a new invocation of the function; use an encryption key generated by taking each byte of the encryption key obtained in step (d) and performing an XOR (exclusive or) operation between that byte and the single-byte value of the iteration counter (from 1 to 19).
h)Store the output from the final invocation of the RC4 function as the value of the O entry in the encryption dictionary.
and
Algorithm 5: Computing the encryption dictionary’s U (user password) value (Security handlers of revision 3 or greater)
a)Create an encryption key based on the user password string, as described in "Algorithm 2: Computing an encryption key".
b)Initialize the MD5 hash function and pass the 32-byte padding string shown in step (a) of "Algorithm 2: Computing an encryption key" as input to this function.
c)Pass the first element of the file’s file identifier array (the value of the ID entry in the document’s trailer dictionary; see Table 15) to the hash function and finish the hash.
d)Encrypt the 16-byte result of the hash, using an RC4 encryption function with the encryption key from step (a).
e)Do the following 19 times: Take the output from the previous invocation of the RC4 function and pass it as input to a new invocation of the function; use an encryption key generated by taking each byte of the original encryption key obtained in step (a) and performing an XOR (exclusive or) operation between that byte and the single-byte value of the iteration counter (from 1 to 19).
f)Append 16 bytes of arbitrary padding to the output from the final invocation of the RC4 function and store the 32-byte result as the value of the U entry in the encryption dictionary.
In both cases step (a) of "Algorithm 2: Computing an encryption key" is referenced:
Algorithm 2: Computing an encryption key
a)Pad or truncate the password string to exactly 32 bytes. If the password string is more than 32 bytes long, use only its first 32 bytes; if it is less than 32 bytes long, pad it by appending the required number of additional bytes from the beginning of the following padding string:
< 28 BF 4E 5E 4E 75 8A 41 64 00 4E 56 FF FA 01 08
2E 2E 00 B6 D0 68 3E 80 2F 0C A9 FE 64 53 69 7A >
That is, if the password string is n bytes long, append the first 32 - n bytes of the padding string to the end of the password string. If the password string is empty (zero-length), meaning there is no user password, substitute the entire padding string in its place.
...

Encryption and decryption with same length of characters in sql server

I want to encrypt string with the same length of character string and decryption with same length of character string using sql server. For Example:
Encryption
Input: Encrypt("002581") -- with 6 characters
Result: a&pE12 -- output with same 6 characters in encrypted form
Decryption
Input: Decrypt("a&pE12") -- with 6 characters
Result: 002581 -- output with same 6 characters in decrypted form
Short answer: there is no such secure encryption scheme.
Longer answer: any kind of encryption scheme obfuscates content of a plain text to be indistinguishable from other messages from the same message space. To do so all cipher texts produced must be of the same length (ideally) regardless of an input plain text. At least the length should be different from a length of a plain text.
So please, don't even consider such an encryption technique. It's insecure by definition.

I understand the mathematics of RSA encryption: How are the files in ~/.ssh related to the theory?

I went through the math in the "worked example" in the RSA wiki page: https://en.wikipedia.org/wiki/RSA_(algorithm) and understood it entirely. For the remainder of this question, I will use math variables consistent with the wiki page.
I'm on a Unix machine and I'm looking in the ~/.ssh directory and I see all these files
id_rsa
id_rsa.pub
and I want to connect the theory with the practice.
What exactly is in id_rsa? If I cat it
cat id_rsa
I get a big jumble of characters. Is this some representation the number n = pq? What representation is it exactly? base 64? If so, then is id_rsa.pub suppose to be some representation of the numbers e and n?
In general, I'm trying to connect the theory of RSA with the actual practice as implemented through the ssh program on Unix machines. Any answers or pointers to the right direction would be greatly appreciated.
id_rsa is a base64-encoded DER-encoded string. The ASN.1 syntax for that DER-encoded string is described in RFC3447 (aka PKCS1):
Version ::= INTEGER { two-prime(0), multi(1) }
(CONSTRAINED BY
{-- version must be multi if otherPrimeInfos present --})
RSAPrivateKey ::= SEQUENCE {
version Version,
modulus INTEGER, -- n
publicExponent INTEGER, -- e
privateExponent INTEGER, -- d
prime1 INTEGER, -- p
prime2 INTEGER, -- q
exponent1 INTEGER, -- d mod (p-1)
exponent2 INTEGER, -- d mod (q-1)
coefficient INTEGER, -- (inverse of q) mod p
otherPrimeInfos OtherPrimeInfos OPTIONAL
}
DER encoding uses a tag-length-value notation. So here's a sample private key:
-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4eCZ0FPqri0cb2JZfXJ/DgYSF6vUp
wmJG8wVQZKjeGcjDOL5UlsuusFncCzWBQ7RKNUSesmQRMSGkVb1/3j+skZ6UtW+5u09lHNsj6tQ5
1s1SPrCBkedbNf0Tp0GbMJDyR4e9T04ZZwIDAQABAoGAFijko56+qGyN8M0RVyaRAXz++xTqHBLh
3tx4VgMtrQ+WEgCjhoTwo23KMBAuJGSYnRmoBZM3lMfTKevIkAidPExvYCdm5dYq3XToLkkLv5L2
pIIVOFMDG+KESnAFV7l2c+cnzRMW0+b6f8mR1CJzZuxVLL6Q02fvLi55/mbSYxECQQDeAw6fiIQX
GukBI4eMZZt4nscy2o12KyYner3VpoeE+Np2q+Z3pvAMd/aNzQ/W9WaI+NRfcxUJrmfPwIGm63il
AkEAxCL5HQb2bQr4ByorcMWm/hEP2MZzROV73yF41hPsRC9m66KrheO9HPTJuo3/9s5p+sqGxOlF
L0NDt4SkosjgGwJAFklyR1uZ/wPJjj611cdBcztlPdqoxssQGnh85BzCj/u3WqBpE2vjvyyvyI5k
X6zk7S0ljKtt2jny2+00VsBerQJBAJGC1Mg5Oydo5NwD6BiROrPxGo2bpTbu/fhrT8ebHkTz2epl
U9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ
37sJ5QsW+sJyoNde3xH8vdXhzU7eT82D6X/scw9RZz+/6rCJ4p0=
-----END RSA PRIVATE KEY-----
Here's the hex encoding:
3082025c02010002818100aa18aba43b50deef38598faf87d2ab634e4571c130a9bca7b878267414
faab8b471bd8965f5c9fc3818485eaf529c26246f3055064a8de19c8c338be5496cbaeb059dc0b35
8143b44a35449eb264113121a455bd7fde3fac919e94b56fb9bb4f651cdb23ead439d6cd523eb081
91e75b35fd13a7419b3090f24787bd4f4e196702030100010281801628e4a39ebea86c8df0cd1157
2691017cfefb14ea1c12e1dedc7856032dad0f961200a38684f0a36dca30102e2464989d19a80593
3794c7d329ebc890089d3c4c6f602766e5d62add74e82e490bbf92f6a482153853031be2844a7005
57b97673e727cd1316d3e6fa7fc991d4227366ec552cbe90d367ef2e2e79fe66d26311024100de03
0e9f8884171ae90123878c659b789ec732da8d762b26277abdd5a68784f8da76abe677a6f00c77f6
8dcd0fd6f56688f8d45f731509ae67cfc081a6eb78a5024100c422f91d06f66d0af8072a2b70c5a6
fe110fd8c67344e57bdf2178d613ec442f66eba2ab85e3bd1cf4c9ba8dfff6ce69faca86c4e9452f
4343b784a4a2c8e01b0240164972475b99ff03c98e3eb5d5c741733b653ddaa8c6cb101a787ce41c
c28ffbb75aa069136be3bf2cafc88e645face4ed2d258cab6dda39f2dbed3456c05ead0241009182
d4c8393b2768e4dc03e818913ab3f11a8d9ba536eefdf86b4fc79b1e44f3d9ea6553d55041243363
5a193155fc8b59b95944cb3f3db22c9201415757aa13024011a88ae4a84a369f52157b8b57041a96
fcf21e4d058673597199dfbb09e50b16fac272a0d75edf11fcbdd5e1cd4ede4fcd83e97fec730f51
673fbfeab089e29d
The 30 is because it's a SEQUENCE tag. The 82025c represents the length. The first byte means the length is of the "long form" (82 & 80) and that the next two bytes represent the length (82 & 7F). So the actual length of the SEQUENCE is 025c. So after that is the value.
Then you get to the version. 02 is of type int, 01 is the tag length and 00 is the value. ie. it's a two-prime key as opposed to a multi-prime key.
More info on the Distinguished Encoding Rules.
Trying to understand ASN.1 is a lot more complicated and a lot of it, for the purpose of understanding the formatting of RSA private keys, is unnecessary. For X.509 it becomes more necessary but RSA keys aren't nearly as complicated, formatting-wise, as X.509 certs.
Hope that helps!

SSL certificate signature verification

I'm trying to verify certificate on an embedded board manually because it doesn't support Openssl or other libraries. However it does have libraries for MD5 and SHA1 hashes and RSA encryption.
From what I understand to verify the certificate, first compute the SHA1 hash (or MD5) of the certificate; then decode the signature using CA's public key to obtain a hashed value. These two hash values should be the same.
SHA1 hash produces a 20 byte value and MD5 produces 16 byte value. However, RSA decoding of the signature does not. If the CA's key is 1024 bits, the decode signature will be 80bytes; if the CA's key is 512 bits, the decoded signature will be 40 bytes. So I can't really compare the 20 bytes SHA1 value against the 40 or 80 bytes Decoded Signature.
Am I doing something wrong? Or am I missing a step?
The missing bit is the padding algorithm.
You use RSA with a specific padding algorithm, and the same algorithm also tells you how to take the result (when you decrypt the signature) and extract from it the actual data (the hash).