Yubico Forum
https://forum.yubico.com/

Protocol question - whose AES-encrypted token is it?
https://forum.yubico.com/viewtopic.php?f=16&t=625
Page 1 of 1

Author:  matthewbloch [ Sat Jan 22, 2011 2:56 am ]
Post subject:  Protocol question - whose AES-encrypted token is it?

I've been playing they my new key, and reading the YubiKey security evaluation and had one question left about the protocol. How does the api.yubico.com server know which of its millions of AES keys to try to decode an incoming token against? e.g. using ykclient, I send 'ykclient 123 ' and finish the line off with a generated token, that goes off to api.yubico.com, right? However from the security evaulation, the token encrypted with a shared secret - however the token doesn't contain any identifier as to *which* secret that might be. I don't know what the client_id field means, but the program detects duff tokens, and replayed tokens. How can it do this without knowing which of its AES secrets to try to decode against?

I can understand that with most sign-on protocols you would also send a username, which would give the server a key to check against. However that doesn't happen here.

I'm clearly missing something about the network service, but I'm not sure how it knows which key it's seeing a token from. Can someone enlighten me?

Author:  matthewbloch [ Sat Jan 22, 2011 3:25 am ]
Post subject:  Re: Protocol question - whose AES-encrypted token is it?

Just to crystallise my confusion before bed :) what is the 'fixed' field and what is the 'uid' field, and how do they appear in the token output? ykpersonalize allows me to set both of these, but the TICKET struct described in the Security Evaluation only mentions the 6-byte uid. If that's the userId field, where does the 'fixed' field come in?

e.g. I am trying to set up YubiPAM 1.1 on my laptop to see the basic protocol work.

I do:

Code:
ykpersonalize  -2 -a1b7c9370433d06a9bdec2500c1a0dffc -ofixed=h:112233445566 \
  -ouid=h:112233445566 -v \
  -osend-ref -o-oath-fixed-modhex


to programme configuration 2.

Then I associate my token with my user ID:

Code:
$ sudo ykpasswd  -a mattbee
Public UID [max 32 hex chars]: 112233445566
Adding Yubikey entry for mattbee
AES key [exactly 32 hex chars]: 1b7c9370433d06a9bdec2500c1a0dffc
Private UID [exactly 12 hex chars]: 112233445566
Completed successfully.


but ykvalidate doesn't like it when I send it a token (I held down the button for the second config):

Code:
ykvalidate  -u mattbee cccccccirlcbbdilbtigutelvjgbnnkgcvhcbifcctfb
mattbee: OTP is INVALID!


Using the Ruby code to try to see what's in my token seems even weirder:

Code:
require 'yubikey'

key = '1b7c9370433d06a9bdec2500c1a0dffc'
otp = readline.chomp
token = Yubikey::OTP.new(otp, key)

p "Device public id: #{token.public_id}"
p "Device secret id: #{token.secret_id}"
p "Device insertions: #{token.insert_counter}"
p "Session activation counter: #{token.session_counter}"
p "Session timestamp: #{token.timestamp}"
p "OTP random data: #{token.random_number}"


yields:

Code:
$ ruby -Ilib examples/otp.rb
cbdefghijklnrtuvbbddeeffgghhfkiregiinhbeefndutgbvlenhflvebbh
"Device public id: cbdefghijklnrtuvbbddeeffgghh"
"Device secret id: 112233445566"
"Device insertions: 65535"
"Session activation counter: 255"
"Session timestamp: 16777215"
"OTP random data: 65535"


that seems good that it can decode the secret-ID, but all the other fields are set to 1s, even after (re)inserting a few times. I assume it's something I've done wrong with ykpersonalize but I can't see what.

Author:  matthewbloch [ Sat Jan 22, 2011 3:34 am ]
Post subject:  Re: Protocol question - whose AES-encrypted token is it?

Excuse the stream of consciousness... this seems to get more sensible results out of the Ruby token decoder:

Code:
ykpersonalize  -2 -a1b7c9370433d06a9bdec2500c1a0dffc -ofixed=h:112233445566 \
  -ouid=h:112233445566 -v -osend-ref -ooath-fixed-modhex -o-static-ticket \
  -o-send-ref -o-strong-pw1 -o-strong-pw2 \
  -o-man-update


outputs:

Code:
$ ruby -Ilib examples/otp.rb
bbddeeffgghhunbcitudbiivnvbunhinjbdcfgivivnb
"Device public id: bbddeeffgghh"
"Device secret id: 112233445566"
"Device insertions: 1"
"Session activation counter: 3"
"Session timestamp: 9295230"
"OTP random data: 55844"


By fiddling around with the ykpersonalize options I seem to be able to get character sequences that don't decode to valid OTP tokens, but are still different each time. From the man page, the default options for -2 are suited for static generation, and the default options for -1 (which I don't want to touch yet while I'm still playing with yubico's servers) are suitable for OTP use. I get the impression setting any of the output options for OTP use make the token useless, but I'm not sure why.

I'm still not sure how the public ID and secret ID relate to each other.

Author:  matthewbloch [ Sat Jan 22, 2011 3:41 am ]
Post subject:  Re: Protocol question - whose AES-encrypted token is it?

OK last post on the subject, promise. The invalid tokens from YubiPAM were due to the fact that "make install" in YubiPAM does not set a necessary binary as setuid, or add a necessary group to your system. Follow the last few steps in the README and it's fine.

Now if someone can explain the options in ykpersonalize, and the difference between public/private IDs I'll be happy :)

Author:  Jakob [ Sun Jan 30, 2011 3:29 am ]
Post subject:  Re: Protocol question - whose AES-encrypted token is it?

I'll summarize a brief description of the Yubikey OTP

The Yubikey OTP is 16 bytes which equals 32 modhex characters. This is the "dynamic" part which changes for every press on the button and by design, each OTP is unique.

The OTP is made up of several fields that are encrypted with a symmetric key before being encoded into modhex format. In order for a validating server to determine which encryption key to use for the decryption operation, the OTP is generally preceeded with a 6-byte unencrypted public identity. The complete OTP then becomes 12 + 32 = 44 bytes in length.

Here, a key with public identity of 11 22 33 44 55 66 yields three OTPs:

bbddeeffgghhintujirljregedjtdnndngnjhnhteuce
bbddeeffgghhtbrrfilctecbuetuvhekhbuulrkhghci
bbddeeffgghhedbvivbeuhhitdtdkuctnduidvrudurb

As seen, the first 12 characters are static, which is the unencrypted public id. This is the modhex representation of 11 22 33 44 55 66 = bbddeeffgghh. Separating the static and the dynamic part, it looks like this:

bbddeeffgghh intujirljregedjtdnndngnjhnhteuce
bbddeeffgghh tbrrfilctecbuetuvhekhbuulrkhghci
bbddeeffgghh edbvivbeuhhitdtdkuctnduidvrudurb

The remaining 32 bytes are the dynamic OTP part. When this string is decrypted with its encryption key, which happens to be 303132333435363738393a3b3c3d3e3f, the fields appear in clear text can be verified.

As a first sanity check, verify the ISO13239 checksum over the decrypted data to verify that the packet is reasonably correct.

Then, verify the 6-byte secret id with the reference value stored in the database for this particular public id.

Then, verify the counter fields so that the OTP is not a replay.

Optionally, the timer value can then be validated to calculate the time delta from a previous request.


When used with a public id, the private id is typically just a random number, stored in the validation server database together with the encryption key. However, the private id can also be used in a "zero footprint" setting, where no public id is sent. All Yubikeys in a specific fleet is then sharing the same encryption key and when decrypted, the private id is used to make a lookup in the database to verify the counter values.


Hope this basic primer brought some light over this subject.

Best regards,

JakobE
Hardware- and firmware guy @ Yubico

Page 1 of 1 All times are UTC + 1 hour
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/