Each TLS1.0 implementation must support the use of the TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA cipher suite. This cipher suite dictates that the server must send a ServerKeyExchange message with the following structures:
struct {
opaque dh_p<1..2^16-1>;
opaque dh_g<1..2^16-1>;
opaque dh_Ys<1..2^16-1>;
} ServerDHParams;
select (SignatureAlgorithm)
{ ....... omitted ........
case dsa:
digitally-signed struct {
opaque sha_hash[20];
};
} Signature;
The sha_hash
value is calculated by SHA(ClientHello.random + ServerHello.random + ServerParams)
then the calculated hash is given to the DSA algorithm to produce the signature (which is in turn encoded in DER). My question is how are the inputs to the DSA derived in this case?
According to wikipedia DSA requires the following parameters:
- N : q length
- L : p length
- q : N-bit prime
- p : L-bit prime modulus such that p-1 is a multiple of q
- g : a number whose multiplicative order modulo p is q
- x : secret key, where
0 < x < q
- y : public key y=g^x mod p
Is the public key (or any other value) the same value that is contained in the X.509 certificate sent by the server? Or all the values are specifically generated for the DSA signature?
Also: I've read somewhere that N and L must be 1024/160. Is this a requirement of the TLS protocol or other values are valid in the context of TLS?
p, q, g
params are contained in the DSA certificate (in theDSS-Params
field) along with the public dsa key (in theSubjectPublicKeyInfo
field). These parameters along with the secret key (private) are contained in the file produced byopenssl dsaparam -genkey 1024 -out dsakey.pem
. Can anyone confirm this is correct?openssl dsa -in dsakey.pem -noout -text
or the neweropenssl pkey (same)
. Or if you suspect openssl of some backchannel, take the second PEM block (your command writes both the parameters and the privatekey as separate blocks), convert the content from base64 to binary, and parse as ASN.1 DER, which can be done by hand from a hex dump with only moderate effort. Also note 1.0 apparently made the MUST-implement suite DSA because the RSA patent was still an issue in 1999; 1.1 changed back to RSA-3DES (not even DHE) and 1.2 to RSA-AES.---BEGIN DSA PARAMETERS---
and---BEGIN DSA PRIVATE KEY---
but when I converted from base64 to der and then decoded the der structure, I found that the first section contained the integers forp, q, g
while the second one (DSA PRIVATE KEY
) contained the former 3 params along with the pub and private keys. Is there a reason why the 3 parameters are repeated in both sections?dsaparam
generated, which is p,q,g. FIPS186 param generation also creates seed and counter, but storing them is optional and openssl doesn't. The second block is labelled PRIVATE KEY and a DSA privatekey is defined as a number x with respect to parameters that are either stored or implied. openssl's 'legacy' representation stores the parameters plus x,y. If you convert to PKCS#8 (or usegenpkey
which creates it) that also stores parameters and x, but not y, which is (trivially) recreated when read.