sudo rm -rf /

(株)アジャストのエンジニアリング?ブログです

Author: adjust (page 1 of 7)

jsで試す暗号化(難読化)

ブログの書き溜めがなくなり、久方ぶりに書くことになりました山本です。

今回は、暗号化(難読化)です。

といっても、複雑な暗号化は私の数学的知識では出来そうにありませんので、とても簡単なものを考えております。

さて、なぜ難読化を行おうと思ったかというと、あるユーザの操作情報をCookieに入れるのですが、その中身を見て気付かれたくなかったり、簡単に加工されたくなかったりといった事が理由でした。
まあ、Cookieを使わずに、Ajaxか何かでサーバと通信してが一番確実なのですが、そこまでする程の情報でもない場合のケースです。

もっとも、分かる人がソース見れば、復号化も出来るわけですから単純にいえば、足切りですね。

暗号化

さて簡単な暗号に、カエサル暗号というものがあります。

値を左右にシフトする暗号です。

例えば、もとの値が「D」であった場合、左に3シフトすると、「A」となります。

wikiからの引用ですが、以下のように変更されます。

平文: THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG
暗号文: QEB NRFZH YOLTK CLU GRJMP LSBO QEB IXWV ALD

まず、これベースにしていきましょう。

カエサル暗号では、アルファベットしか使用しないので、シフトが簡単ですが、日本語を使うとなると少々面倒になります。

なので、Base64にしてしまいましょう。
(IE10未満は使用出来ないので、切り捨てです)

String.prototype.b64encode = function(){
  return btoa(unescape(encodeURIComponent(this)));
};
String.prototype.b64decode = function(){
  return decodeURIComponent(escape(atob(this))); 
};

var word     = 'あいうえお';
var original = word.b64encode().split('');
var newWord  = [];
var offs     = 10;

for (i in original){
  var code = original[i].charCodeAt(0);
  newWord.push(String.fromCharCode(code + offs));
}

console.log(newWord.join(''));

右に10シフトした結果です。

?As@>>UPAAƒo?As@>>YA>ys:?As@AA5C

簡単に難読化が出来ました。

が、ブラウザ上では分かりませんがAAとo?の間に一箇所抜けが出ています。

これは、y:121に10を加算すると131となり、ASCIIの範囲を超えてしまうからですね。
ですので、ASCIIの範囲を超える場合、循環するように調整を行う必要があります。

また、復号化の際に問題が出そうな気がする制御文字、0~31と127ですが、これも除外します。

方法としてはその文字のコードから32引いて、その数字を(127-32+1)で割り、そこから余りを出し、32を加算することで可能でしょう。
32以下の制御文字が入っていた場合、問題が発生しますが、そもそも制御文字を暗号化する必要があるとは思えないので無視します。

var asciiLimit   = 126;
var asciiExclude = 32;
var asciiOffset  = asciiLimit - asciiExclude + 1;

for (i in original){
  var code = original[i].charCodeAt(0);
  newWord.push(String.fromCharCode(((code - asciiExclude + offs) % asciiOffset) + asciiExclude));
}

調整すると、制御文字が出ないようになりました。

?As@>>UPAA$o?As@>>YA>ys:?As@AA5C

シフト数を調整する

ベースは出来たので、複雑にしていきます。

まず、固定の数値分シフトするのは少々面白くないので、シフトする数を可変としましょう。
とはいえ、ランダムでは復号化出来ないので何かしらの法則性を設ける必要があります。

for (i in original){
  var offs = Math.round(Math.pow(i, 2) + (Math.pow(i, 3) / 10));
  var code = original[i].charCodeAt(0);
  newWord.push(String.fromCharCode(((code - asciiExclude + offs) % asciiOffset) + asciiExclude));
}

少々安易ですが、文字それぞれに、左から数えて何文字目かを二乗して、それに同じ値を三乗して10で割った数を足し、四捨五入した数だけシフトするようにしました。
言葉にすると分かりにくいですが

1 : (1 * 1) + (1 * 1 * 1 / 10) = 1.1 = 1
2 : (2 * 2) + (2 * 2 * 2 / 10) = 4.8 = 5
3 : (3 * 3) + (3 * 3 * 3 / 10) = 11.7 = 12

計算式にするとそれ程複雑ではありません。

今回は手間なので行いませんが、10で割っているところに、振り幅を入れてみたり
現在二乗と、三乗をしていますが、これを偶数、奇数、素数、任意の約数等の条件でn乗になるようにすれば更に分かりにくくなるのではと思います。

ダミーを混ぜる

現在、シフトはしていますが本物のデータのみとなっています。
ここにダミーも混ぜるようにすると強度が増しますね。きっと。

段階的に進めていきましょう。

まずは一つおきに、簡単にダミーが入るように調整します。
とりあえずダミーなので、ランダムの値を入れておきます。

for (i in original){
  var offs = Math.round(Math.pow(i, 2) + (Math.pow(i, 3) / 10));
  var code = original[i].charCodeAt(0);
  newWord.push(String.fromCharCode(((code - asciiExclude + offs) % asciiOffset) + asciiExclude));
  newWord.push(String.fromCharCode($.getRoundom(asciiExclude + 1, asciiLimit)));
}

ダミーが入るようになりました。

で、ここで問題なのですが

1回目:5M8mnVB4J>ZY&W:qKUr#$%FAUz@7dg/{58Hf$!9LpZ5j’RT=oZ:ZEv[OY@iI!_fZ
2回目:5q8an1B-J/Z@&l:iKSr7$HFaUs@&dw/g5WH3$+9’pu5i’rT of:LE1[JYui&!jfB
3回目:5l8?n(BMJvZn&Z:3KXri$LF\UM@tdA/^5<HX$C9Op!5s’OT*o4:<EH[XY5i5!2fX

ダミーがランダムだと、差分でどの値がダミーであるかが判別出来てしまいます。

なので、ランダムは避けたほうが良いでしょう。

var getRangeValue = function(code, offs){
  return ((code - asciiExclude + offs) % asciiOffset) + asciiExclude
};

for (i in original){
  var offs = Math.round(Math.pow(i, 2) + (Math.pow(i, 3) / 10));
  var code = original[i].charCodeAt(0);
  newWord.push(String.fromCharCode(getRangeValue(code, offs)));
  newWord.push(String.fromCharCode(getRangeValue(code + Math.pow(code, 3), 0)));
}

一個前の文字のコードに、同じコードの3乗を足してみました。

1回目:5A8Un<BgJ<Z<&7:xKUrU$zF UA@Ud</g5<H<$D9Up<5z'<T<oA:UE<[gYUiU!#f_
2回目:5A8Un<BgJ<Z<&7:xKUrU$zF UA@Ud</g5<H<$D9Up<5z'<T<oA:UE<[gYUiU!#f_
3回目:5A8Un<BgJ<Z<&7:xKUrU$zF UA@Ud</g5<H<$D9Up<5z'<T<oA:UE<[gYUiU!#f_

並び替える

さて、ダミーを足すところまでやりました。

ただ、一文字おきというのは少々安易です。

正しい文字がバラけて、かつダミーの数、順番に波を設けます。

うまくバラけるようにしたいのですが、私の数学的 知識では良いアイディアがないので

以下のように、ある程度簡単に振り分けを行います。

123456789

864213579

そして、各文字の間にダミー文字を入れていきます。

入れる個数については、ひとつ前の文字のコードから、末尾一桁の数だけ入れていきます。

String.prototype.obfuscateEncode = function(){
  var word     = String(this);
  var original = word.b64encode().split('');
  var newWord  = [];
  var result   = [];

  var asciiLimit   = 126;
  var asciiExclude = 32;
  var asciiOffset  = asciiLimit - asciiExclude + 1;

  var getRangeValue = function(code, offs){
    return ((code - asciiExclude + offs) % asciiOffset) + asciiExclude
  };

  for (var i in original){
    var offs = Math.round(Math.pow(i, 2) + (Math.pow(i, 3) / 10));
    var code = original[i].charCodeAt(0);
    if (i % 2 == 0){
      newWord.push(getRangeValue(code, offs));
    }
    else{
      newWord.unshift(getRangeValue(code, offs));
    }
  }

  for (var i in newWord){
    var keyNumber = String(newWord[i]).charAt(String(newWord[i]).length - 1);
    var prevCode  = newWord[i];
    result.push(String.fromCharCode(newWord[i]));
    for (var j = 0; j < keyNumber; j++){
      prevCode = getRangeValue(prevCode + Math.pow(prevCode, j), 0)
      result.push(String.fromCharCode(prevCode));
    }
  }

  return result.join('');
}
fgoiju~Wb[\:;vM(K7d(TUK__56lW9:tRF7PnHI3/0`ai#s(@A#xFFrs(xF:;vM(K7d(ZBC'(i#s89r____56lWnJK7(i&'NRF7PnUKL9L9&$%J(i#sUVMtCId56lW$%J(i#spq$'(Ps(K7d(}opEF-K7Zd2dUYZUZ<As(#<!"D%

はい、難読化してみました。

もはや、原型をとどめていませんせんね。

復号化

次は、復号化です。

まず、今までおこなってきたものを逆順にするだけです。

バラして、要らないの消す?
のは簡単でした。

次に、シフトした値を戻して終わりになる予定なんですが。。。。
値を戻すことが出来なくなりました。

暗号化した際には、逆から計算すばいいから大丈夫だろうぐらいしか考えて居なかったので
よくよく考えてみると、余りはあるのですが商の値が存在しないので逆算が出来ない。

とりあえず、コードを総当りすれば出来るのでそれでやってみます。

String.prototype.obfuscateDecode = function(){
  var word = String(this).split('');
  var w1   = [];
  var w2   = [];

  for (var i = 0; i < word.length; i++){
    var code = word[i].charCodeAt(0);
    w1.push(code);
    i += parseInt(String(code).charAt(String(code).length - 1));
  }

  var length = w1.length;
  for (var i = 0; i < length; i++){
    if (i % 2){
      var v = w1.pop();
    }
    else{
      var v = w1.shift();
    }

    var foo = length - i - 1
    var offs = Math.round(Math.pow(foo, 2) + (Math.pow(foo, 3) / 10));

    w2.unshift(String.fromCharCode(v.getOriginalCode(offs)));
  }
  return w2.join('').b64decode();
}

一応これで復号化出来るようになりました。
方法としてはかなり不本意ですが。

やはり復号化するというのが、結構面倒ですね。

今回も、暗号化した文字列内に商を保持しておけば総当りしなくも良かったわけですが、それをどこに含ませるのか。
いざ自分で作ってみると考えなくてはいけないことが多そうです。

「AutoDraw」は自分が求めるアイコンを表示してくれるのか試してみた

皆さんこんちは。
このブログを始めた頃は自分が部内で一番の下っ端だったのですが、気づけば自分の後に5人も入ってきたので先輩風を吹かすのに毎日忙しいライパチ藤田でございます。
プログラマーの腕は既に抜かれているな~と思っているのはここだけの秘密です。

随分前からの悩みで、資料を作成する際にいつもいい感じのアイコンを探したり、イラレが使える人にこんな感じでと言ってアイコンを作ってもらったりと資料を作成するのに結構な時間をかけていました。
今話題の「AutoDraw」の説明動画を見ていたら、もしかしてアイコン作るときにこれを使えば自分が描いた絵でいい感じのアイコンが作れて資料作成する時間を短縮できるんじゃないかと思い色々と試してみました。

Continue reading

Symfony2管理画面構築バンドル[Sonata Admin]を触ってみよう(2/2)

こんにちは。
最近、暖かくもなってきたし登山に復帰しようかと思ってる武田です。

前回に引き続き、Symfony2管理画面構築バンドル[Sonata Admin]を触っていこうと思います。

前の物を拡張する形で以下の機能を追加していきます。

  • 項目「タグ」の追加
  • 画像のアップロード
  • バリデーション
  • 日本語化

Continue reading

Symfony2管理画面構築バンドル[Sonata Admin]を触ってみよう(1/2)

こんにちは。
先日、酔っ払って帰宅中にメガネを紛失した武田です。

最近、Symfony2というフレームワークを利用するようになりました。
一般的な管理画面の機能であるCRUDをけっこう楽に作れるバンドルがあったので紹介してみたいと思います。
※Symfony2のドキュメントって日本語の物が少ないのでちょっとでも増やせればなんて思ってます。。。

今回はsonataAdminチュートリアルをベースに環境構築、シンブルなブログ用CRUD作成してみようと思います

実験環境

以下のバージョンで進めていきます。

  • Cent OS 6.8 64bit
  • PHP 7.0.13
  • symfony 2.8
  • MySQL 5.7.16

まずは環境構築からやっていきます。

Continue reading

Doctrine2をyamlで使う

久々に投稿します。株式会社アジャストの渕上です。
PHPにはDoctrineというORMがあります。

弊社では受託案件で特にフレームワークの指定がない場合、
「Symfony」を採用することが多いため、ORMはDoctrineを利用することが多いです。

Continue reading

Unityを、まったくの初心者が触るとどうなるか?(1/2)

結論から申し上げますと、ブログ締め切りぎりぎりの投稿になります。
マークアップエンジニアの竹橋です。よろしくお願いいたします。

ということで今回は、ゲーム統合開発環境として名高いUnityを触ってみたいと思います。
ゲーム開発というとめちゃくちゃプログラムな印象があるのですが、私のように、プログラムをそんなにかけない人間でも作れるのか、チャレンジしてみたいと思います。

Continue reading

みんなでボードゲームをやろう!

皆さま、はじめまして。

ソーシャルキャストチームで営業を担当しておりますの中野(なかの)と申します。
今年は年男です。
どうぞよろしくお願いいたします。

今回は趣をかえまして、部署内でボードゲームをやってみたいと思います。
ちょっとしたレクリエーションです。
チームの親睦を深めたいと思います。

遊ぶボードゲームは「枯山水」というゲームです。
会社の方が持っていたのをお借りしました。

Continue reading

Chrome Developer Tools の便利な使い方

皆さま、はじめまして。
マークアップエンジニアの竹橋(たけはし)と申します。
BMI指数は27.2です。よろしくお願いいたします。

私は、ウェブサイトのフロントエンドを触ることが多く、「Chrome Developer Tools」には大変お世話になっております。
今回はこの神ツールを使っていて、実務上とっても役にたった便利な使い方や、ちょっとマニアックなやつやらをご紹介したいと思います!
※Chromeのバージョンは55です。

Continue reading

スマートフォンアプリを作ろう

こんにちは、山本です。

さて、Goで作るAndroidアプリの続きの予定、、、だったんですが実際使ってみると問題が色々と浮き彫りとなってまいりました。

まず、GPSを使いたかったんですが、Go mobileに取得するモジュールが見つからなかったり、画面表示をOpenGLで直にで行うなどコストが高すぎたり、やっぱりIDEが使いたかったりと、このまま進めていくのが少々難しくなってきました。

なんというか、Goでスマホアプリを作るのはまだまだ発展途上ということですかね。

とはいえ、ここで終了というのも面白くありませんので、別のアプローチを取ろうかと思います。

Continue reading

IPv6の普及について色々調べてみた

皆さんこんにちは。”sudo rm -rf -“界の「ライトで8番」藤田でございます。
今年も早いもので残り1週間弱になりましたが、皆さん今年のやり残しはございませんでしょうか?
私は随分前から”藤田は仕事以外を考えるのをやめた”状態で生活をしております。まぁ~単なる現実逃避です。
それにしても今年は1月から世間的にも私生活的にも色々なことがありすぎて慌ただしい2016年でございました。

Continue reading

Older posts

© 2017 sudo rm -rf /

Theme by Anders NorenUp ↑