goのcfbとmcryptのcfb
mcryptで書かれた3DES+CFBのEncrypt/Decryptをgoで書き直すことになったので、ハマったところのメモ。
そもそも3DES(DES)とは
DESを3回(暗号化->復号->暗号化)をやって強度を高めたもの。 DESは下記がわかりやすい。
CFB(Cipher FeedBack)モード
DESはブロック暗号方式なのでブロックごとに暗号化する。 ただ、普通に暗号するだけでは総当たり攻撃などでKeyが推測されるリスクがあるため、暗号化時に前後のブロックを工夫して使う。 その方法(モード)の一つにCFB(Cipher FeedBack)がある。
CFBモードは平文ブロックを直接暗号化するのではなく、その前のブロックの暗号化ブロックをさらに暗号化し、その結果と平文のxorをとる。 最初のブロックに対しては初期化ブロックを暗号化する。
ハマったところ
このCFBにはsegmentという概念(DESのブロックサイズとは別)がある。 segmentが何かと言うと、xorを取る暗号化ブロックの一部(segument size)だけを利用する、というもの。 詳しくはNIST Special Publication 800-38aに書いてある(これを理解することは不可能だろう)。
segment sizeが8bitなら、8bitごとにxorをとっていく。そして平文の最初の8bitを暗号化するために暗号化ブロックの最初の8bitを使う。 そして次のブロックの暗号化を行う際、再び暗号化を行った結果を使ってxorを取る。
これをgoで書くとこんな感じ。
func (x *cfb) XORKeyStream(dst, src []byte) { for i := range src { x.b.Encrypt(x.out, x.in) copy(x.in[:x.blockSize-1], x.in[1:]) if x.decrypt { x.in[x.blockSize-1] = src[i] } dst[i] = src[i]^x.out[0] if !x.decrypt { x.in[x.blockSize-1] = dst[i] } } }
mcryptの場合、CFBのsegment sizeは8bit。
CFB: The Cipher-Feedback Mode (in 8bit). This is a self-synchronizing stream cipher implemented from a block cipher.
copyで暗号化ブロックから1byte分を使って、1byteの平文だけxorをとっている。 それを平文全体に対して繰り返す。
それに対して、goの標準ライブラリに含まれるCFBの実装は以下のようになっている。
func (x *cfb) XORKeyStream(dst, src []byte) { if len(dst) < len(src) { panic("crypto/cipher: output smaller than input") } if subtle.InexactOverlap(dst[:len(src)], src) { panic("crypto/cipher: invalid buffer overlap") } for len(src) > 0 { if x.outUsed == len(x.out) { x.b.Encrypt(x.out, x.next) x.outUsed = 0 } if x.decrypt { // We can precompute a larger segment of the // keystream on decryption. This will allow // larger batches for xor, and we should be // able to match CTR/OFB performance. copy(x.next[x.outUsed:], src) } n := xorBytes(dst, src, x.out[x.outUsed:]) if !x.decrypt { copy(x.next[x.outUsed:], dst) } dst = dst[n:] src = src[n:] x.outUsed += n } }
基本的にoutUsedは暗号化のブロックサイズが入る。今回の環境ではブロックサイズは8byteだったので、8byte単位に暗号化&xorを行っていたため、Encrypt/Decryptがうまくいかないという状態だった。
最後に
暗号化は詳しくないので間違ってる可能性あります。 アリスの国に行かねば。
friendly iframe
friendly iframeとは
A Friendly IFrame is an IFrame that shares the same domain as the main page it is hosted on. This generally means that the content is trusted and hence, >can ‘break out’ of the IFrame and manipulate the content on the hosting page. Friendly IFrame is some kind of interactive and communicating frame.
Adform | Friendly and non-Friendly IFrames
とのことで、親ページと同じオリジンのiframe。これはsrcを指定しないでiframeを作ると勝手にそうなる。
同じくadformより。
How to recognize a friendly ifame? Usually it’s source attribute ‘src’ is set to a small advertisement page file in the same domain as the page or ‘src’ is set to “about:self”.
about:selfはwebkitだとエラーになる(ソースちら見したらemptyかabout:blankのみ)ので、srcには何も指定しないのが無難。
friendly iframeは親とオリジンが同じなので、iframeの中からiframe自体にアクセスができる。 friendly iframeに対応しているかどうかはInDapIFという変数を定義するようにとIABからのお達しがあるので、これを使って↓みたいなことができる。
if(typeof inDapIF !== "undefined" && inDapIF === true){ var w = window.parent.screen.width; var iframe = window.parent.document.getElementsByTagName('iframe')[0]; iframe.style.width = w + 'px'; } // ここから広告表示 document.write('<div style="width:100%;height:100%;background-color:#000;"><div>');
iframe配下に書き出させる広告scriptのイメージ。こんなコードは使えないけど。
friendly iframeに対応していればiframeの横幅をmaxにして広告表示できる。 CORSとかどうなんだろって思ってたけど、結局サーバ側の設定だからあまりfriendly iframeとは関連がない。