33 *
44 * Ported from https://github.com/equipter/mfkey by li0ard
55 */
6- import { crypto1_byte , lfsr_recovery64 , lfsr_rollback_byte , lfsr_rollback_word , prng_successor } from "../src"
6+ import { lfsr_recovery64 , prng_successor } from "../src" ;
77
88if ( process . argv . length < 7 ) {
9- console . log ( 'Usage: [bun/node] ' + process . argv [ 1 ] + ' <uid> <tag challenge> <reader challenge> <reader response> <tag response>' )
10- console . log ( 'Example: [bun/node] mfkey64.ts 14579f69 ce844261 f8049ccb 0525c84f 9431cc40' )
11- process . exit ( 1 )
9+ console . log ( 'Usage: [bun/node] ' + process . argv [ 1 ] + ' <uid> <tag challenge> <reader challenge> <reader response> <tag response>' ) ;
10+ console . log ( 'Example: [bun/node] mfkey64.ts 14579f69 ce844261 f8049ccb 0525c84f 9431cc40' ) ;
11+ process . exit ( 1 ) ;
1212}
1313
14- const dec2hex = ( dec : number , bits : number ) => {
15- if ( dec < 0 ) {
16- return ( Math . pow ( 2 , bits ) + dec ) . toString ( 16 ) . padStart ( bits / 4 , '0' )
17- } else {
18- return dec . toString ( 16 ) . padStart ( bits / 4 , '0' ) ;
19- }
20- }
14+ const dec2hex = ( dec : number , bits : number ) : string => ( dec < 0 ) ? ( Math . pow ( 2 , bits ) + dec ) . toString ( 16 ) . padStart ( bits / 4 , '0' ) : dec . toString ( 16 ) . padStart ( bits / 4 , '0' ) ;
2115
22- const uid = parseInt ( process . argv [ 2 ] , 16 )
23- const chal = parseInt ( process . argv [ 3 ] , 16 )
24- const rchal = parseInt ( process . argv [ 4 ] , 16 )
25- const rresp = parseInt ( process . argv [ 5 ] , 16 )
26- const tresp = parseInt ( process . argv [ 6 ] , 16 )
16+ const uid = parseInt ( process . argv [ 2 ] , 16 ) ;
17+ const chal = parseInt ( process . argv [ 3 ] , 16 ) ;
18+ const rchal = parseInt ( process . argv [ 4 ] , 16 ) ;
19+ const rresp = parseInt ( process . argv [ 5 ] , 16 ) ;
20+ const tresp = parseInt ( process . argv [ 6 ] , 16 ) ;
2721
28- let encc = process . argv . length - 7
29- let enclen : number [ ] = Array ( encc )
30- let enc : number [ ] [ ] = Array . from ( { length : encc } , ( ) => new Array ( 120 ) ) ;
22+ const encc = process . argv . length - 7 ;
23+ const enclen : number [ ] = Array ( encc ) ;
24+ const enc : number [ ] [ ] = Array . from ( { length : encc } , ( ) => new Array ( 120 ) ) ;
3125
3226for ( let i = 0 ; i < encc ; i ++ ) {
3327 enclen [ i ] = ( process . argv [ i + 7 ] . length ) / 2 ;
34- for ( let i2 = 0 ; i2 < enclen [ i ] ; i2 ++ ) {
35- enc [ i ] [ i2 ] = parseInt ( process . argv [ i + 7 ] . substring ( i2 * 2 , i2 * 2 + 2 ) , 16 )
36- }
28+ for ( let i2 = 0 ; i2 < enclen [ i ] ; i2 ++ ) enc [ i ] [ i2 ] = parseInt ( process . argv [ i + 7 ] . substring ( i2 * 2 , i2 * 2 + 2 ) , 16 ) ;
3729}
3830
3931console . log ( `MIFARE Classic key recovery - based 64 bits of keystream
@@ -42,51 +34,47 @@ Recovering key for:
4234 nt: ${ dec2hex ( chal , 32 ) }
4335 {nr}: ${ dec2hex ( rchal , 32 ) }
4436 {ar}: ${ dec2hex ( rresp , 32 ) }
45- {at}: ${ dec2hex ( tresp , 32 ) } \n` )
37+ {at}: ${ dec2hex ( tresp , 32 ) } \n` ) ;
4638
4739for ( let i = 0 ; i < encc ; i ++ ) {
48- process . stdout . write ( `{enc${ i } }: ` )
49- for ( let i2 = 0 ; i2 < enclen [ i ] ; i2 ++ ) {
50- process . stdout . write ( dec2hex ( enc [ i ] [ i2 ] , 8 ) )
51- }
52- console . log ( "" )
40+ process . stdout . write ( `{enc${ i } }: ` ) ;
41+ for ( let i2 = 0 ; i2 < enclen [ i ] ; i2 ++ ) process . stdout . write ( dec2hex ( enc [ i ] [ i2 ] , 8 ) ) ;
42+ console . log ( "" ) ;
5343}
5444
55- const p64 = prng_successor ( chal , 64 )
45+ const p64 = prng_successor ( chal , 64 ) ;
5646console . log ( `\nLFSR successors of the tag challenge:
5747 nt': ${ dec2hex ( p64 , 32 ) }
58- nt'': ${ dec2hex ( prng_successor ( p64 , 32 ) , 32 ) } \n` )
48+ nt'': ${ dec2hex ( prng_successor ( p64 , 32 ) , 32 ) } \n` ) ;
5949
60- const ks2 = rresp ^ p64
61- const ks3 = tresp ^ prng_successor ( p64 , 32 )
50+ const ks2 = rresp ^ p64 ;
51+ const ks3 = tresp ^ prng_successor ( p64 , 32 ) ;
6252
6353console . log ( `Keystream used to generate {ar} and {at}:
6454 ks2: ${ dec2hex ( ks2 , 32 ) }
65- ks3: ${ dec2hex ( ks3 , 32 ) } \n` )
55+ ks3: ${ dec2hex ( ks3 , 32 ) } \n` ) ;
6656
67- let s = lfsr_recovery64 ( ks2 , ks3 ) [ 0 ]
57+ const s = lfsr_recovery64 ( ks2 , ks3 ) [ 0 ] ;
6858
6959if ( process . argv . length > 7 ) {
70- console . log ( "Decrypted communication:" )
60+ console . log ( "Decrypted communication:" ) ;
7161 let ks4 = 0 ;
7262 let rollb = 0 ;
7363 for ( let i = 0 ; i < encc ; i ++ ) {
74- process . stdout . write ( `{dec${ i } }: ` )
64+ process . stdout . write ( `{dec${ i } }: ` ) ;
7565 for ( let i2 = 0 ; i2 < enclen [ i ] ; i2 ++ ) {
76- ks4 = crypto1_byte ( s , 0 ) ;
77- process . stdout . write ( dec2hex ( ks4 ^ enc [ i ] [ i2 ] , 8 ) )
66+ ks4 = s . byte ( 0 ) ;
67+ process . stdout . write ( dec2hex ( ks4 ^ enc [ i ] [ i2 ] , 8 ) ) ;
7868 rollb += 1 ;
7969 }
80- console . log ( "" )
70+ console . log ( "" ) ;
8171 }
82- for ( let i = 0 ; i < rollb ; i ++ ) lfsr_rollback_byte ( s , 0 )
72+ for ( let i = 0 ; i < rollb ; i ++ ) s . rollback_byte ( 0 ) ;
8373}
84- let postAuthState = s . lfsr
85-
86- lfsr_rollback_word ( s , 0 )
87- lfsr_rollback_word ( s , 0 )
88- lfsr_rollback_word ( s , rchal , true )
89- lfsr_rollback_word ( s , uid ^ chal )
74+ const postAuthState = s . lfsr ;
75+ s . rollback_word ( ) ;
76+ s . rollback_word ( ) ;
77+ s . rollback_word ( rchal , true ) ;
78+ s . rollback_word ( uid ^ chal ) ;
9079
91- console . log ( `\nFound Key: [${ s . lfsr . toString ( 16 ) . padStart ( 12 , "0" ) } ]
92- Post-auth state: [${ postAuthState . toString ( 16 ) . padStart ( 12 , "0" ) } ]` )
80+ console . log ( `\nFound Key: [${ s . lfsr . toString ( 16 ) . padStart ( 12 , "0" ) } ]\nPost-auth state: [${ postAuthState . toString ( 16 ) . padStart ( 12 , "0" ) } ]` ) ;
0 commit comments