T-110.5211 Cryptosystems (4 cr)

Assignment FAQ


NOTE: This information is LIKELY TO CHANGE during the course!

T-110.5211 Cryptosystems Programming Assignment

(More or less) Frequently Asked Questions


3DES-CBC-EDE

Q: I am having a problem with 3DES implementation. I managed to make the test application run through the first encryption, but it fails on decryption.
  • A1: Even though the encryption function returns the correct result, it corrupts the incoming byte array given to it. The decryption also works correctly, but since the comparison value (= correct plaintext) was corrupted by the encryption function, comparison fails.
    Easy fix: clone the incoming block byte[] on encryption and decryption to avoid changing the input.
  • A2: Check your decryption; if the encryption uses EDE, then what is the decryption procedure? Also remember the order of subkeys in decryption.

Hash functions

Q: Can I use Java's ready implementations of MD5 and SHA1?

A: You should use CryptoUtil to get MD5 or SHA1 hash instances, capable of computing hashes. (If you happened to use Java's MessageDigest, that's also OK.)


Digital signatures

Q: How is the 'digitally-signed' data actually encoded?

A: digitally-signed is defined in Section 4.7 of RFC 2246. From the TLS point of view, a signed data element is an opaque data item:

			In digital signing, one-way hash functions are used as input for a
	signing algorithm. A digitally-signed element is encoded as an opaque
	vector <0..2^16-1>, where the length is specified by the signing
	algorithm and key.
	

For RSA, Section 4.7 states:

			In RSA signing, a 36-byte structure of two hashes (one SHA and one
	MD5) is signed (encrypted with the private key). It is encoded with
	PKCS #1 block type 0 or type 1 as described in [PKCS1].
	
You can get PKCS #1 v1.5 from here: PKCS #1 v1.5. (NOTE: Don't use the newer, v2.1 of PKCS #1, TLS doesn't use it.)

Note that PKCS #1 defines a signature mechanism for signing large messages. This mechanism requires you to first hash the input data and then apply the RSA private key operation. Since the data in TLS is already fixed size (36 bytes), this mechanism is *not* used in TLS. Instead, the server simply performs a private key operation on the hash data directly.

PKCS #1 v1.5 Section 8 describes the RSA encryption process. In particular, Section 8.1 describes the block types 0 (00) and 1 (01). After applying the public key operation to the signature (to recover the original data), you need to: (1) check that the RSA padding is correct (properly formatted with type 0 or 1), and that (2) the 36-octet signed (MD5 & SHA1) hash value is correct.


Q: What does signature verification actually require?

A: You need four things:

  1. First, you need the public key from the server certificate. You also need to extract the public key exponent and the modulus from the key. See java.security.interfaces.RSAKey, java.security.interfaces.RSAPublicKey, java.security.interfaces.RSAPrivateKey.
  2. Second, you need to compute the 36-byte value (which is signed by the server), see CryptoUtil.get{Md5,Sha1}Instance(). The relevant definitions for this are in RFC 2246 Section 7.4.3:
    						
    		struct {
    		opaque dh_p<1..2^16-1>;
    		opaque dh_g<1..2^16-1>;
    		opaque dh_Ys<1..2^16-1>;
    		} ServerDHParams;     /* Ephemeral DH parameters */
    		
    		struct {
    		select (KeyExchangeAlgorithm) {
    		        case diffie_hellman:
    		            ServerDHParams params;
    		            Signature signed_params;
    		case rsa:
    		ServerRSAParams params;
    		Signature signed_params;
    		};
    		} ServerKeyExchange;
    		params
    		The server's key exchange parameters.
    		signed_params
    		For non-anonymous key exchanges, a hash of the corresponding
    		params value, with the signature appropriate to that hash
    		applied.
    		md5_hash
    		MD5(ClientHello.random + ServerHello.random + ServerParams);
    		sha_hash
    		SHA(ClientHello.random + ServerHello.random + ServerParams);
    		enum { anonymous, rsa, dsa } SignatureAlgorithm;
    		select (SignatureAlgorithm)
    		{   case anonymous: struct { };
    		case rsa:
    		        digitally-signed struct {
    		            opaque md5_hash[16];
    		            opaque sha_hash[20];
    		        };
    		case dsa:
    		digitally-signed struct {
    		opaque sha_hash[20];
    		};
    		} Signature;
    		
    NOTE: There are two gotchas in this part of the RFC. First, there is a slight typo in the RFC definition. The value ServerParams refers in our case actually to ServerDHParams; ServerParams isn't defined anywhere in the RFC. Second, the ServerParams value refers to the TLS-encoded form of the value (i.e. with the length-value encoding of Section 4 intact): the fields have a two-byte length field preceding them. The client and server random values do not have this field, because they are fixed size; the TLS encoding (Section 4) does not include a length field for fixed length arrays.
  3. Third, you need to apply the public key operation to decrypt the signature. As part of this process, you must verify that the RSA padding is correct, as specified in PKCS #1 (block type 0 or 1).
  4. Fourth, you need to ensure that the signed 36-byte value matches the one you computed yourself.

Https client

Q: After receiving the data, the client gets some alert (content type 21). Should I be worried?

A: If this happens after you got the data, it is probably just the server closing the connection by time-out. (Our client does not handle clean connection closing.) No need to worry, it's a feature of the client ;-)

Q: Where can I find a server which returns more than one certificate in the server Certificate message?

A: Try https://www.mozilla.org/, it seems to have a certificate chain of four certificates.

Q: How can I test that my implementation handles expired certificates correctly?

A: Change host time to the past (beyond the notBefore validity field of the certificate) and run the client; then change the host time to the future (beyond the notAfter validity field of the certificate) and run the client again.
NB: www.tml.hut.fi used to have an expired certificate (and we recommended that as a server for expiration test) but as of at least 28.11.2005 the certificate is again valid.