A 回答 (4件)
- 最新から表示
- 回答順に表示
No.4
- 回答日時:
> 平文が5の倍数の文字数でない場合に、謎文字列を追加したものが返ってくる件なのですが、
> 残り文字の計算の仕方がわからないので、正規表現で数字のみを返すようにしようと思うのですが、
> この謎文字に数字が含まれることってありますかね?
くっつく謎文字列は何が入ることもありえるので、正規表現で数字か調べるのはあまり役に立たないと思います。Base32エンコードは5バイトのデータを8文字で表現したものなので、Base32エンコードするとデータの長さは8/5倍、デコードすると5/8倍になります。つまり、12文字の暗号化+Base32エンコードされた文字を復号すると、floor(12 * 5 / 8)バイトのデータが出てきます。これを元にsubstrすれば良いかもしれません。
暗号化という要望だったので単純に暗号化しましたが、このコードには改ざんをチェックするコードが一切ついていないので、実用する場合は元のデータのSHA256などのハッシュ値 (あるいはその一部) を元のデータに追加して、復号後にチェックしたほうがいいです。ECBモードやCBCモードではないので、一部の文字列の改ざんは他に伝搬せず、改ざんがあっても復号された文字からはわかりません。もちろん、復号された値が数字かチェックするという方法も10/256回試すと当たるのであまり役に立ちません。
http://oshiete.goo.ne.jp/qa/7476282.html のようなことを考えているなら1~10000までの数字はこちらの#2さんの回答にあるとおり2バイトで表現できるので、自分だったら2バイトでIDを表現したものに4バイトのハッシュ値を付けます。
コードに書くとこんな感じです。(Base32の不具合を治すコードも入れたつもりです。)
改ざんを検出すると、数字の代わりに-1を返します。
$number = '12345';
$key = "This is a key.";
$salt = "This is a salt.";
$c = new NumberCodec($key, $iv);
$cipher_text = $c->encode($number);
print $cipher_text."\n";
print strlen($cipher_text)."\n";
print $c->decode($cipher_text,0)."\n";
print $c->decode(substr($cipher_text,1))."\n";
/**
* Number Encoder/Decoder.
* Encoded string will have digital signature, and encrypted.
* The digital signature will be verified at decode time.
*
* @package default
* @author Hanabutako.
*/
class NumberCodec {
function __construct($password, $salt) {
$this->my_crypt = new MyCrypt($password, $salt);
}
/**
* Encode a given number.
*
* @param $number number to be encoded.
* @return base32 encoded encrypted string with digital signature.
*/
function encode($number) {
$number_hex = sprintf("%x", intval($number));
if (strlen($number_hex) % 2 != 0) { $number_hex = "0$number_hex"; }
$number_hexbin = hex2bin($number_hex);
$digest = substr(hex2bin(hash('sha256', $number_hexbin)), 0, 4);
return $this->my_crypt->encrypt($digest . $number_hexbin);
}
/**
* Decode from a given string.
*
* @param $encrypted_string encrypted string.
* @return number if verify suceeded. Otherwise, -1.
*/
function decode($encrypted_string) {
$decoded_length = floor(strlen($encrypted_string) * 5 / 8);
$decrypted = substr($this->my_crypt->decrypt($encrypted_string),
0, $decoded_length);
$digest = substr($decrypted, 0, 4);
$hexbin = substr($decrypted, 4);
if (substr(hex2bin(hash('sha256', $hexbin)), 0, 4) != $digest) {
return -1;
}
return intval(bin2hex($hexbin), 16);
}
}
No.3
- 回答日時:
元の平文が8文字未満なら、CTRモード、OFBモード、あるいはCFBモードで暗号化して、Base32でエンコードすればよいと思います。
実際のコードはこんな感じです。
$plain = 'abcdefg';
$key = "This is a key.";
$salt = "This is a salt.";
$c = new MyCrypt($key, $iv);
print $c->encrypt($plain) . "\n";
print strlen($c->encrypt($plain)) . "\n";
print $c->decrypt($c->encrypt($plain)) . "\n";
/**
* Encrypt/Decrypt string.
* Encrypted value is encoded with Base32.
*
* package default
* author Hanabutako.
*/
class MyCrypt {
function __construct($password, $salt) {
$this->base32 = new Base32();
$this->td = mcrypt_module_open('rijndael-256', '', 'ctr', '');
$key_size = mcrypt_enc_get_key_size($this->td);
$iv_size = mcrypt_enc_get_iv_size($this->td);
$this->key = str_hash_pbkdf2($password, $salt, 10, $key_size, 'sha256');
$this->iv = str_hash_pbkdf2($password, $salt, 10, $iv_size, 'sha256', 32);
}
function __destruct() {
mcrypt_module_close($this->td);
}
/**
* Encrypt the given plain text.
*
* @return base32 encoded encrypted string.
*/
function encrypt($plain) {
mcrypt_generic_init($this->td, $this->key, $this->iv);
$encrypted = mcrypt_generic($this->td, $plain);
mcrypt_generic_deinit($this->td);
return $this->base32->encode($encrypted, $padding=false);
}
/**
* Decrypt the given cipher text encoded with Base32.
*
* @return decrypted plain text.
*/
function decrypt($encrypted) {
$decoded = $this->base32->decode($encrypted);
mcrypt_generic_init($this->td, $this->key, $this->iv);
$plain = mdecrypt_generic($this->td, $decoded);
mcrypt_generic_deinit($this->td);
return $plain;
}
}
文字数オーバーしたのでライブラリーは省略しています。
Base32のライブラリーはここから調達して、不具合があったので手直ししました。
http://php.net/manual/en/function.base-convert.php
このライブラリーは8文字にアラインされていない場合の扱いが雑なので、その部分を調整する必要があります。この不具合のために平文が5の倍数の文字数でない場合に、謎文字列を追加したものがかえってきます。decode処理で残り文字列を計算して、残り文字列以上書かせない様にすれば治ります。
PBKDF2のライブラリーはここから調達しました。
http://php.net/manual/ja/function.hash-hmac.php
まぁ、実装の一例ということで。
この回答へのお礼
お礼日時:2012/05/24 00:10
回答ありがとうございます。
とても参考になりました!助かりました(^^)
平文が5の倍数の文字数でない場合に、謎文字列を追加したものが返ってくる件なのですが、
残り文字の計算の仕方がわからないので、正規表現で数字のみを返すようにしようと思うのですが、この謎文字に数字が含まれることってありますかね?
No.2
- 回答日時:
英字大小+数字=56種が12文字で、71.45ビットを表現できるから、ブロック長が64ビットの暗号を使えばよいかと。
www.php.netのMCryptリファレンスに使用例がありますので、そちらを読んでみては。
ただ、本来の目的が
http://oshiete.goo.ne.jp/qa/7476282.html
> ユーザーIDが1~10000まであるとするとそれぞれのIDを8文字の英数字に暗号化したくなった場合
――にあるのだとしたら、そもそもユーザIDを暗号化する必然性がないし、暗号化するならば英数12文字以下なんて制約をつけるのはちょっとアレかもと思えたり。
No.1
- 回答日時:
復号可能な暗号化という条件ですよね?「指定した文字」の長さと文字種はどういう条件でしょうか。
暗号化する以上、元の文字数より長くなることはあっても短くはなりません。mcryptで利用可能な暗号化形式で(元の文字列長が短くても)英数字のみで12文字未満ってありましたっけ?記号を含むどころかバイナリが生成される形式はたくさんありますが・・・。さすがに「全部試してみた」という方も少ないとは思います。ご自身では「試してみよう」というおつもりはないのでしょうかね。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- JavaScript HTMLでJavaScriptを使ってパスワードの強化判定のプログラムを作成しています。 一通り作っ 2 2022/10/19 01:41
- その他(プログラミング・Web制作) 文字コード及びフォントに関する次の記述を読み,適切なものをすべて選べ。 ASCIIとは,英数字だけを 4 2023/01/11 19:10
- Excel(エクセル) エクセルの数式で教えてください。 2 2023/03/09 16:55
- その他(IT・Webサービス) パスワードで○文字以内、とかの規定があるのはなぜ? 4 2022/06/28 13:13
- Visual Basic(VBA) エクセルの数式で教えてください。 1 2023/07/31 15:49
- Excel(エクセル) VBAで “:” を含むセルの特定 2 2023/05/11 16:30
- その他(プログラミング・Web制作) COBOL数値転記をCOPY句内での仕様 6 2022/06/15 18:48
- その他(セキュリティ) パスワードは、この先もずっと無くならないのでしょうか?大文字、小文字の英字、数字、記号からなら8ケタ 2 2022/10/30 18:00
- PHP カラーミーショップのSmartyでの文字列抜き出し 2 2022/05/06 11:51
- その他(職業・資格) ローソンの会員になりたいです。 パスワードを打ってます。 英大文字、小文字、数字を含めて8文字以上打 3 2022/12/19 11:18
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・【大喜利】【投稿~12/2】 国民的アニメ『サザエさん』が打ち切りになった理由を教えてください
- ・ちょっと先の未来クイズ第5問
- ・【お題】ヒーローの謝罪会見
- ・これが怖いの自分だけ?というものありますか?
- ・スマホに会話を聞かれているな!?と思ったことありますか?
- ・それもChatGPT!?と驚いた使用方法を教えてください
- ・見学に行くとしたら【天国】と【地獄】どっち?
- ・【大喜利】【投稿~11/22】このサンタクロースは偽物だと気付いた理由とは?
- ・お風呂の温度、何℃にしてますか?
- ・とっておきの「まかない飯」を教えて下さい!
- ・2024年のうちにやっておきたいこと、ここで宣言しませんか?
- ・いけず言葉しりとり
- ・土曜の昼、学校帰りの昼メシの思い出
- ・忘れられない激○○料理
- ・あなたにとってのゴールデンタイムはいつですか?
- ・とっておきの「夜食」教えて下さい
- ・これまでで一番「情けなかったとき」はいつですか?
- ・プリン+醤油=ウニみたいな組み合わせメニューを教えて!
- ・タイムマシーンがあったら、過去と未来どちらに行く?
- ・遅刻の「言い訳」選手権
- ・好きな和訳タイトルを教えてください
- ・うちのカレーにはこれが入ってる!って食材ありますか?
- ・おすすめのモーニング・朝食メニューを教えて!
- ・「覚え間違い」を教えてください!
- ・とっておきの手土産を教えて
- ・「平成」を感じるもの
- ・秘密基地、どこに作った?
- ・カンパ〜イ!←最初の1杯目、なに頼む?
- ・この人頭いいなと思ったエピソード
- ・あなたの「必」の書き順を教えてください
- ・ギリギリ行けるお一人様のライン
- ・10代と話して驚いたこと
- ・大人になっても苦手な食べ物、ありますか?
- ・14歳の自分に衝撃の事実を告げてください
- ・家・車以外で、人生で一番奮発した買い物
- ・人生最悪の忘れ物
- ・あなたの習慣について教えてください!!
- ・都道府県穴埋めゲーム
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
VBSで"をエスケープする文字は?
-
不規則なaタグのスクレイピング...
-
Pukiwikiの編集にて#や-を無効...
-
mb_ereg_replace関数の正規表現
-
c# string型の変数に、ダブルク...
-
VBAのコマンドボタンの文字列の...
-
エスケープ文字の復帰(¥r)と...
-
ソースコードの1行が長いとき...
-
メッセージボックスで1025文字...
-
エクセルのCOUNTIFが正しくカウ...
-
改行を読み飛ばす
-
文字の入力で横バー上段、中断...
-
Replace関数は文字数の制限ある...
-
VBA ASC関数で変換できない文...
-
カンマの含まれる文字列の数値...
-
PHPmailerでの添付ファイルの文...
-
秀丸の正規表現で複数行にわた...
-
fputsで改行できない
-
delphi でのコード上でTab を入...
-
CSVファイルの改行コード判別
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
VBSで"をエスケープする文字は?
-
ダブルコーテーション(
-
文字列の置換をCStringで(C++)
-
PHPの¥
-
○分から○時間○分に変換
-
文字列の括弧について(初心者)
-
c# string型の変数に、ダブルク...
-
(から)までの文字列を削除したい
-
ダブルクォーテーションが置換...
-
文字列のアスタリスク置換
-
nl2brが効かないのですが・・・
-
2バイトローマ数字小文字につ...
-
【PHP】preg_replace() で正...
-
文章から指定した範囲の文字列...
-
REGEXREPLACE関数について、
-
htmlspecialchars関数でエスケ...
-
php 正規表現で、\\マークを取...
-
mcryptで英数字(12未満)のみに...
-
近似した文字列を置換するエク...
-
ダブル、シングルクォーテーシ...
おすすめ情報