RobThree / TwoFactorAuth

PHP library for Two Factor Authentication (TFA / 2FA)
MIT License
1.07k stars 126 forks source link

Best storage type for secret in database #4

Closed matheustav closed 8 years ago

matheustav commented 8 years ago

Hi!

Sorry if this is not the right place for it, but I would like to know which is the best datatype to save the secret in my db (I'm using Mysql).

These are my configs: digits = 6, period = 60, algorithm = sha1.

Thanks!

RobThree commented 8 years ago

You can simply store it as varchar? If that's not the answer you're looking for then please explain a bit more.

matheustav commented 8 years ago

Rob, thanks for your reply. I'll try to explain better:

The secret seems to be always a string with 16 chars, like "JBSWY3DPEHPK3PXP". So, to save space in my DB, I would choose for a CHAR(16), but I'm not sure about how this key is created and if it's always the same size.

RobThree commented 8 years ago

The length of the secret depends on the number of bits you specify for the createSecret() method; the default (when no argument is provided to the createSecret() method) is 80 bits (which is also the minimum you'll want to use*) and results in a 16 chars long secret.

$tfa = new TwoFactorAuth('MyCompany', 6, 30, 'sha1');
for ($i = 8; $i <= 160; $i+=8) {
  $s = $tfa->createSecret($i);
  echo $i . 'bits; example code: "'. $s . '" Length: ' . strlen($s) . PHP_EOL;
}
8bits;   example code: "7E"                               Length: 2
16bits;  example code: "N3I6"                             Length: 4
24bits;  example code: "V42IV"                            Length: 5
32bits;  example code: "KB6HZUY"                          Length: 7
40bits;  example code: "VDRMNKFS"                         Length: 8
48bits;  example code: "PGGAEAAAD6"                       Length: 10
56bits;  example code: "HNUZL5AMDN3C"                     Length: 12
64bits;  example code: "CIXF36U43XWEE"                    Length: 13
72bits;  example code: "7TNIUC7UGLLEU7R"                  Length: 15
80bits;  example code: "IXWTNY2XSNWRND4T"                 Length: 16
88bits;  example code: "K6KGKLRNWEDJZXCYNQ"               Length: 18
96bits;  example code: "VAP6TJLYPVM457RTAJBP"             Length: 20
104bits; example code: "2E46WAVPMRAKK2MQFFQMH"            Length: 21
112bits; example code: "72FRZRMS6RADLH722ILWQ6C"          Length: 23
120bits; example code: "ZTIXXCITTKHAWTKQZP7UEGVR"         Length: 24
128bits; example code: "SGKAK7NWIOLK4RTYPQF5QKF727"       Length: 26
136bits; example code: "PFMQRIOSCHMDWGS7AM5RANDOE7KF"     Length: 28
144bits; example code: "KKGVMCTDYCKPAMZ64XD7BRWAOB7HQ"    Length: 29
152bits; example code: "ZPD5GXIQLPIC2JKUSWXPBPGFK3VCCY7"  Length: 31
160bits; example code: "YUD6JGRZDJUJKELDIAGSXMKPX3GNEGQB" Length: 32

As long as you don't change the $bits argument the output length will be constant and can be calculated as:

length = ceil(number_of_bits / 5)


* Unfortunately not all TOTP applications support arbitrary values. "Safe" values should be 80, 128, 160 and such "common" values; if you want to stay on the safe side (TOTP application support wise) your best bet for wide support will be 80.

matheustav commented 8 years ago

Thank you so much, Rob. Now it's clearer for me.

RobThree commented 8 years ago

You're welcome :+1: