Quantcast
Channel: C#タグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 8895

C#でRC4(Arcfour)を計算する

$
0
0

内容

PDFでRC4(Arcfour)が使われる場面があり、
Arcfourの計算は、.NETの既存クラスでは対応していないようなので、Arcfourを計算するコードを書いてみた。
一応テストベクタとは一致してそうですが、ご利用は自己責任でお願いします。

Arcfourは安全性が十分でないとして、今後は使われなくなる流れのようです。
https://ja.wikipedia.org/wiki/RC4

※RC4は登録商標のため、RC4を謳うとまずいらしい
http://e-words.jp/w/RC4.html

参考サイト

https://tools.ietf.org/html/draft-kaukonen-cipher-arcfour-03#ref-CRYPTLIB

ソースコード

参考サイトの内容を実装

usingSystem;usingSystem.IO;publicclassArcfour{byte[]_S;// S-Boxbyte[]_key;byte_Index;byte_J;Arcfour(){}publicstaticArcfourCreateArcfour(byte[]key){Arcfourret=newArcfour();if(key.Length<5){returnnull;}ret._key=newbyte[key.Length];Array.Copy(key,0,ret._key,0,key.Length);// _key[i] = key[i]ret._S=InitializeSBox(ret._key);ret._Index=0;ret._J=0;returnret;}// 3.1 Key Setupstaticbyte[]InitializeSBox(byte[]key){// step.1.byte[]S=newbyte[256];// step.2.for(inti=0;i<256;i++){// ループカウンタをbyteにするとoverflowして無限ループするはずなので注意S[i]=(byte)i;}// step.3.byte[]S2=newbyte[256];for(inti=0;i<256;i++){S2[i]=key[i%key.Length];}// step.4.intj=0;for(inti=0;i<256;i++){j=(byte)(j+S[i]+S2[i]);bytetemp=S[i];S[i]=S[j];S[j]=temp;}// step.5. セキュリティの観点でメモリにゴミが残らないようi,j,S2を0クリア推奨されている。// (iをクリアしても意味ないような)// 効果が不明だがクリアしておく。j=0;for(inti=0;i<256;i++){S2[i]=0;}returnS;}// 3.2 Stream Generation// EncryptとDecryptは同一処理publicvoidEncrypt(Streamsrc,Streamdest,intlength){for(intcount=0;count<length;count++){intsByte=src.ReadByte();if(sByte<0){return;}// End of stream_Index++;_J+=_S[_Index];bytetemp=_S[_Index];_S[_Index]=_S[_J];_S[_J]=temp;temp=(byte)(_S[_Index]+_S[_J]);byteK=_S[temp];dest.WriteByte((byte)(((byte)sByte)^K));// XOR}}}// -------------------------------------------------------------classArcfourTest{staticvoidTest1(){byte[]plain=newbyte[8];// all zerobyte[]chipher=newbyte[8];byte[]key=newbyte[]{0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF};// 128bitArcfourarcfour=Arcfour.CreateArcfour(key);MemoryStreamsrc=newMemoryStream(plain,false);// 第2引数=falseでreadonlyMemoryStreamdest=newMemoryStream(chipher);arcfour.Encrypt(src,dest,plain.Length);src.Close();dest.Close();DumpBytes(chipher);}staticvoidTest1d(){byte[]plain=newbyte[]{0x74,0x94,0xC2,0xE7,0x10,0x4B,0x08,0x79};byte[]chipher=newbyte[8];byte[]key=newbyte[]{0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF};// 64bitArcfourarcfour=Arcfour.CreateArcfour(key);MemoryStreamsrc=newMemoryStream(plain,false);// 第2引数=falseでreadonlyMemoryStreamdest=newMemoryStream(chipher);arcfour.Encrypt(src,dest,plain.Length);src.Close();dest.Close();DumpBytes(chipher);}staticvoidTest2(){//  Cipher Text:   0xf1, 0x38, 0x29, 0xc9, 0xdebyte[]plain=newbyte[]{0xdc,0xee,0x4c,0xf9,0x2c};byte[]chipher=newbyte[5];byte[]key=newbyte[]{0x61,0x8a,0x63,0xd2,0xfb};// 40bitArcfourarcfour=Arcfour.CreateArcfour(key);MemoryStreamsrc=newMemoryStream(plain,false);// 第2引数=falseでreadonlyMemoryStreamdest=newMemoryStream(chipher);arcfour.Encrypt(src,dest,plain.Length);src.Close();dest.Close();DumpBytes(chipher);}staticbyte[]TestVector3_PlainText=newbyte[]{0x52,0x75,0x69,0x73,0x6c,0x69,0x6e,0x6e,0x75,0x6e,0x20,0x6c,0x61,0x75,0x6c,0x75,0x20,0x6b,0x6f,0x72,0x76,0x69,0x73,0x73,0x73,0x61,0x6e,0x69,0x2c,0x20,0x74,0xe4,0x68,0x6b,0xe4,0x70,0xe4,0x69,0x64,0x65,0x6e,0x20,0x70,0xe4,0xe4,0x6c,0x6c,0xe4,0x20,0x74,0xe4,0x79,0x73,0x69,0x6b,0x75,0x75,0x2e,0x20,0x4b,0x65,0x73,0xe4,0x79,0xf6,0x6e,0x20,0x6f,0x6e,0x20,0x6f,0x6e,0x6e,0x69,0x20,0x6f,0x6d,0x61,0x6e,0x61,0x6e,0x69,0x2c,0x20,0x6b,0x61,0x73,0x6b,0x69,0x73,0x61,0x76,0x75,0x75,0x6e,0x20,0x6c,0x61,0x61,0x6b,0x73,0x6f,0x74,0x20,0x76,0x65,0x72,0x68,0x6f,0x75,0x75,0x2e,0x20,0x45,0x6e,0x20,0x6d,0x61,0x20,0x69,0x6c,0x6f,0x69,0x74,0x73,0x65,0x2c,0x20,0x73,0x75,0x72,0x65,0x20,0x68,0x75,0x6f,0x6b,0x61,0x61,0x2c,0x20,0x6d,0x75,0x74,0x74,0x61,0x20,0x6d,0x65,0x74,0x73,0xe4,0x6e,0x20,0x74,0x75,0x6d,0x6d,0x75,0x75,0x73,0x20,0x6d,0x75,0x6c,0x6c,0x65,0x20,0x74,0x75,0x6f,0x6b,0x61,0x61,0x2e,0x20,0x50,0x75,0x75,0x6e,0x74,0x6f,0x20,0x70,0x69,0x6c,0x76,0x65,0x6e,0x2c,0x20,0x6d,0x69,0x20,0x68,0x75,0x6b,0x6b,0x75,0x75,0x2c,0x20,0x73,0x69,0x69,0x6e,0x74,0x6f,0x20,0x76,0x61,0x72,0x61,0x6e,0x20,0x74,0x75,0x75,0x6c,0x69,0x73,0x65,0x6e,0x2c,0x20,0x6d,0x69,0x20,0x6e,0x75,0x6b,0x6b,0x75,0x75,0x2e,0x20,0x54,0x75,0x6f,0x6b,0x73,0x75,0x74,0x20,0x76,0x61,0x6e,0x61,0x6d,0x6f,0x6e,0x20,0x6a,0x61,0x20,0x76,0x61,0x72,0x6a,0x6f,0x74,0x20,0x76,0x65,0x65,0x6e,0x2c,0x20,0x6e,0x69,0x69,0x73,0x74,0xe4,0x20,0x73,0x79,0x64,0xe4,0x6d,0x65,0x6e,0x69,0x20,0x6c,0x61,0x75,0x6c,0x75,0x6e,0x20,0x74,0x65,0x65,0x6e,0x2e,0x20,0x2d,0x20,0x45,0x69,0x6e,0x6f,0x20,0x4c,0x65,0x69,0x6e,0x6f};staticbyte[]TestVector3_Key=newbyte[]{0x29,0x04,0x19,0x72,0xfb,0x42,0xba,0x5f,0xc7,0x12,0x77,0x12,0xf1,0x38,0x29,0xc9};staticvoidTest3(){byte[]plain=TestVector3_PlainText;//Array.Copy(TestVector3_PlainText, 0, plain, 0, plain.Length);byte[]chipher=newbyte[plain.Length];byte[]key=TestVector3_Key;Arcfourarcfour=Arcfour.CreateArcfour(key);MemoryStreamsrc=newMemoryStream(plain,false);// 第2引数=falseでreadonlyMemoryStreamdest=newMemoryStream(chipher);arcfour.Encrypt(src,dest,plain.Length);src.Close();dest.Close();DumpBytes(chipher);}staticvoidTest3_2(){byte[]plain=TestVector3_PlainText;//Array.Copy(TestVector3_PlainText, 0, plain, 0, plain.Length);byte[]chipher=newbyte[plain.Length];byte[]key=TestVector3_Key;Arcfourarcfour=Arcfour.CreateArcfour(key);MemoryStreamsrc=newMemoryStream(plain,false);// 第2引数=falseでreadonlyMemoryStreamdest=newMemoryStream(chipher);arcfour.Encrypt(src,dest,50);arcfour.Encrypt(src,dest,50);arcfour.Encrypt(src,dest,50);arcfour.Encrypt(src,dest,50);arcfour.Encrypt(src,dest,50);arcfour.Encrypt(src,dest,50);arcfour.Encrypt(src,dest,50);arcfour.Encrypt(src,dest,50);src.Close();dest.Close();DumpBytes(chipher);}staticvoidDumpBytes(byte[]a){boolfirst=true;foreach(bytebina){if(!first){Console.Write(" ");}Console.Write(b.ToString("x2"));first=false;}Console.WriteLine();}[STAThread]staticvoidMain(string[]args){Test3_2();}}

Viewing all articles
Browse latest Browse all 8895

Trending Articles