no title
某P2Pの初期パケットの RC4 key は null 文字(\x00)以降は使ってはいけない件。最初からトラックバックにしておけば良かったわけですが、こんな感じで確認できます。
#!/usr/bin/perl use warnings; use strict; use IO::Socket::INET; use Crypt::RC4; use Term::ANSIColor qw(:constants); $Term::ANSIColor::AUTORESET = 1; my $host = ''; my $port = 0; for my $i (1..100) { my $socket = IO::Socket::INET->new( PeerAddr => $host, PeerPort => $port, Proto => 'tcp', ); my $buf; $socket->recv( $buf, 11 ); my( $passphrase, $encrypted ); eval { ( $passphrase, $encrypted ) = unpack "x2a4a5", $buf; }; if ($@) { warn "failed unpack : $buf : $@\n"; next; } my $passphrase2 = ( split /\x00/, $passphrase )[0]; print "-" x 70, "\n"; if ( $passphrase =~ /\x00/ ) { print YELLOW "passphrase has null\n"; print RESET; } printf "count = %s\n", $i; printf "passphrase = %s\n", unpack( "H*", $passphrase ); printf "encrypted = %s\n", unpack( "H*", $encrypted ); my( $decrypted1, $decrypted2 ); eval { $decrypted1 = RC4( $passphrase, $encrypted ); $decrypted2 = RC4( $passphrase2, $encrypted ); }; if ($@) { warn "failed RC4 : $@\n"; next; } printf "decrypted1 = %s\n", unpack( "H*", $decrypted1 ); printf "decrypted2 = %s\n", unpack( "H*", $decrypted2 ); $socket->close; }
これの実行結果を抜粋します。
count = 73 passphrase = 56502f18 encrypted = 113b004d27 decrypted1 = 0100000061 decrypted2 = 0100000061 ---------------------------------------------------------------------- passphrase has null count = 74 passphrase = d50026d3 encrypted = 32a174e234 decrypted1 = 5462b63502 decrypted2 = 0100000061 ---------------------------------------------------------------------- count = 75 passphrase = c7b3c526 encrypted = bd2d8b09cf decrypted1 = 0100000061 decrypted2 = 0100000061
74 回目の passphase に null が含まれているのですが、そのままだと正しく decode されないので null 文字以降を切捨てる必要があります。
ところで最初が null 文字の時の正しい decode 方法を僕は知りません。なんかあるのかな。