Skip to content

Instantly share code, notes, and snippets.

@dlenski
Last active May 10, 2022 21:17
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save dlenski/e4a53a17c0786f492fc04c901968681d to your computer and use it in GitHub Desktop.
Save dlenski/e4a53a17c0786f492fc04c901968681d to your computer and use it in GitHub Desktop.
Fake server for RSA SecurID token generation (see https://github.com/dlenski/rsa_ct_kip#fake-server)
#!/usr/bin/env python3
# Needs: Python 3.5+, Flask, PyCryptoDome
# server.pem, rsapubkey.pem + rsaprivkey.pem (1024-bit) in the current directory
#
# What it does:
# Pretends to be the "CT-KIP" web service (https://tools.ietf.org/html/rfc3948) that
# RSA SecurID Token for Windows v5.0.x talks to to set up a new token, using an
# authentication code.
#
# This has been turned into a "real" repository.
#
# See https://github.com/dlenski/rsa_ct_kip#fake-server and use that instead of
# the (no-longer-maintained) contents of this gist.
@dlenski
Copy link
Author

dlenski commented Sep 7, 2018

dsLen = (desired length of K_TOKEN)

K_TOKEN = CT-KIP-PRF (R_C, "Key generation" || k || R_S, dsLen)

@cemeyer, aha, good catch… thanks. A little bit above it, k is defined as the key k used to encrypt R_C. That means the final token key material is supposed to be:

K_TOKEN = CT-KIP-PRF (ClientNonce, "Key generation" || ServerRSAPubKey || ServerNonce, dsLen)

Do you agree that this is right? If so, what do you think is the representation that should be used for "the key k used to encrypt R_C"? The modulus of the key in big-endian order… the standard-ish binary .der format key… the PEM-format key… something else…?

If that's narrowed down then, based on §3.8.6:

MAC = CT-KIP-PRF (K_AUTH, "MAC 2 computation" || R_C, dsLen)
    =  CT-KIP-PRF (K_TOKEN, "MAC 2 computation" || R_C, dsLen)

(because "If no authentication key is present in the token, and no K_TOKEN existed before the CT- KIP run, K_AUTH shall be the newly generated K_TOKEN.")

It seems like most of the magic strings may be documented in the RFC. Worth a shot?

In order to verify whether any of this works we have to get a whole bunch of fiddly bits right:

  1. Ensure that we have a correct implementation of CT-KIP-PRF-AES (rather hard given lack of test vectors and the fact that no one besides RSA would use this).
  2. Guess or know the correct representation of the k used in generating K_TOKEN.
  3. Use the PRF, the k, and the nonces to generate the 16-byte K_TOKEN (assuming RSA's own software adheres to §3.5).
  4. Assuming that K_AUTH = K_TOKEN is indeed correct (as §3.8.6 suggests), use all that to generate the "MAC" and attach it to the <ServerFinished> message.
  5. If the official client software actually accepts the result, then 🍻. If not, then… keep stabbing around blindly and twiddling all of the above knobs… ?

@cemeyer
Copy link

cemeyer commented Sep 8, 2018

Yeah, that looks plausibly right to me.

I hope the RSA pubkey representation fed into the PRF isn't .der and especially PEM, but I don't really know. Could try the DER order (modulus n, followed by exponent e), but I don't know how long of an encoding e would have. Then again PKCS 1 specifies e=65537, so maybe just try the (big-endian, i.e., I2OSP) modulus (which should have an exact encoding width).

I agree that K_TOKEN for K_AUTH looks reasonable for §3.8.6.

Yeah. I've hunted around a little bit and I'm having trouble finding any other CT-KIP-PRF implementation to compare against (not the same as known test vectors, but better than nothing). I wonder if the (single) MAC in https://tools.ietf.org/html/draft-nystrom-ct-kip-two-pass-01#page-30 is a valid test vector. But I have not investigated what it is supposed to be over, or if the key is even supplied.

Um, call me crazy, but isn't CT-KIP-PRF-AES identical to DSKPP-PRF-AES? Even the diagrams and language in RFC 6063 seem derivative of RFC 4758. And indeed our friend Magnus who authored the first RFC is an author on the second. Still no explicit known vectors, but some different MACs that may or may not be correct, anyway. Or maybe there are implementations, I don't know (didn't find any with a very quick google search).

Yeah, we have a very low information oracle on whether we got it right. Hmm. Maybe reversing the client would be more straightforward.

By the way, I don't get notifications of gist replies, so I might miss further discussion here. But we have lots of options :-).

@leonardorobertolopez
Copy link

hi, I would like to ask what is the functionality of this code. Is it a localhost server where I could emulate SecureId app? Thank you very much

@dlenski
Copy link
Author

dlenski commented May 10, 2022

Is it a localhost server where I could emulate SecureId app? Thank you very much

@leonardorobertolopez Yes. To be clear, it emulates the server used for provisioning SecurID tokens using the "RSA CT-KIP" protocol.

It has been turned into a "real" repository, though. See https://github.com/dlenski/rsa_ct_kip#fake-server and use that instead.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment