LlXorBase64/ja

From Second Life Wiki
< LlXorBase64
Revision as of 14:05, 22 November 2023 by Misaki Vanilla (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

要約

関数: string llXorBase64( string str1, string str2 );

正確には、二つの Base64 文字列に対して排他的論理和 (XOR) を実行します。
str1str2 の Base64 XOR です。を string で返します。

• string str1 Base64 文字列
• string str2 Base64 文字列

str2 は、str1 よりも短い場合は繰り返されます。もし入力が Base64 文字列でない場合、結果は不規則になります。
暗号アルゴリズムを設計する前に Cryptography セクションを確認してください。

警告

  • バイト配列への変換時に、str1str2 から最後の (bitcount % 8) が破棄されます。詳細については Implementation を参照してください。

サンプル

default
{
    state_entry(){
        
        // Use a HARD password ! with caps nocaps numbers and symbols !
        string pass = "P4s5Wo_rD";
        
        string data = "I am some ver important data.";
        
        // Enccrypting the data:
        string crypt = llXorBase64(llStringToBase64(data), llStringToBase64(pass));
        
        // Say the mess you made to Owner
        llOwnerSay(crypt);
        
        // DeCrypting the data and say back to owner:
        llOwnerSay(llBase64ToString(llXorBase64(crypt, llStringToBase64(pass))));
        
    }
 
}
// Stronger encryption - generates a random encrypted string.
//safe character set
string ASCII = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";

//convert integer to characters
string chr(integer i)
{
    return llGetSubString(ASCII, i, i);
}

//for generating a random string.
string salt(integer amount) {
    string salt = "";
    integer i;
    //for length of salt , generate characters
    for(i = 0; i < amount; i++) {
        salt += chr((integer)llFrand(llStringLength(ASCII)));
    }
    return salt;
}    

default
{
    touch_start(integer n) {
        //generates a random salt to add to the string.
        //put salt on the end so that even if the data is corrupted by SVC-6362, it is unimportant data
        string data = "I am some very important data." + salt((integer)llFrand(5)+ 5);

        string pass = "password";

        // Encrypting the data:
        string crypt = llXorBase64(llStringToBase64(data), llStringToBase64(pass));
 
        // Say the mess you made to Owner
        llOwnerSay(crypt);
 
        // DeCrypting the data and say back to owner: Remember to remove the salt when needed ;)
        llOwnerSay(llBase64ToString(llXorBase64(crypt, llStringToBase64(pass))));

    }
}

注意点

実装

XOR は、各 Base64 文字列 str1 および str2 をバイト配列に変換し、それらの二つのバイト配列を XOR して行います。最後に、結果のバイト配列を再び Base64 に変換し、ユーザーに返します。

ただし、バイト配列への変換時には最後の (bitcount % 8) が破棄されます。LSL では Base64 文字列を 8 ビットのバイト配列として扱います。6 ビットのバイトの配列ではありません。

暗号学

このセクションで提供されている情報は決して網羅的ではありませんが、読者には十分な情報が提供され、正しい質問をすることや将来の読書をガイドすることができるでしょう。暗号アルゴリズムの作成は、暗号学の理解なしに試みてはならないことであり、そうでないと結果は壊滅的となる可能性があります。

暗号学では、「秘密」は暗号アルゴリズムを変換するために使用される入力情報のビットです。この「秘密」は、アルゴリズムの後続の実行で変化しません。また、「シード」もアルゴリズムを変換するために使用されますが、「秘密」とは異なり変異します。変異の方法はアルゴリズムの一部です。

秘密とシードを効果的に使用するには、次のいずれかを少なくとも2つ秘密にしておく必要があります:1) アルゴリズム、 2) シード、または 3) 秘密。

信じてもらえるかもしれませんが、アルゴリズムを秘密にしても保護されません。XOR アルゴリズムに対して使用できる攻撃ベクトルは、アルゴリズムに対するほとんどまたは全く知識が必要ないものです。最良の保護は、複数の秘密/シードを使用する強力なアルゴリズムです。これにより、前提条件を解釈することによって前提条件を満たすことができます。攻撃者に静的なコードのブロックを提供しないでください。攻撃者に提供する情報が多いほど、アルゴリズムは単純になります。

ベストプラクティス

XOR は暗号技術としては弱いものであり、XOR 入力を決定するために利用できる攻撃がいくつかあります。秘密がどのように使用されているかによって、単一のメッセージを解読することが秘密を明らかにし、導かれたアルゴリズムが破られる可能性があります。

秘密を秘密にしておくこと。XOR と使用する前に、ビットを振るうためにシードされたトラップドア関数を使用し、シードを頻繁に変更します。

異なる長さの2つの値でXOR演算を行う場合、その影響を知っておくことなく実行しないでください。良いアイデアのように思えるかもしれませんが、実際にはフィールドをリンクさせることになります。これにより、より長いキー値(長さの "Wikipedia logo"Least Common Multiple)が得られますが、フィールドは "Wikipedia logo"Greatest Common Divisor だけ存在することになります。ユニークなフィールドの数は、攻撃者が試す必要がある理論上の最大キー数を決定します。

Unique_Key_Fields = Greatest_Common_Divisor(lengths_of_keys) * number_of_keys

攻撃ベクトル

最初に知っておくべきことは、XOR は制限された多項式暗号です。ポリアルファベティック暗号に対して機能する攻撃ベクトルは、XOR に対しても機能します。

  • 確率: 英語では、文字は文法や綴りのルールにより発生する確率が異なります。XOR は文字の確率を隠さない。この攻撃は、キーがメッセージよりもはるかに小さい場合にのみ機能します。
  • UTF-8 ルール: 文字列を Base64 に変換するとき、まず UTF-8 エンコードが使用されます。入力が有効な UTF-8 エンコードであると仮定すれば、ビットのいくつかは観察だけで決定できます。これは主にキーの長さを決定するのに役立ちます。
  • プレーンテキスト: ユーザーは既知の入力に対する出力をキャプチャすることで、キーの脆弱性を明らかにすることができます。
  • 総当たり攻撃: キー、秘密、および/またはシードへの攻撃

PHPでのデコード方法

PHP スクリプトは LSL Wiki にあります。 コードの以前のバージョンはこちらにあります:PHP での llXorBase64StringsCorrect。 SignpostMarv のデコーダの PHP による実装。

<?php
/* 
 * Description: Implementation of SignpostMarv's php base64 decoder.
 * Author: Kopilo Hallard
 * License: http://creativecommons.org/licenses/by-sa/2.5/
 */

/* Cipher (s1 data, s2 key) */
function llXorBase64($s1, $s2) {
    $s1 = base64_decode($s1); $l1 = strlen($s1);
    $s2 = base64_decode($s2);
    if($l1 > strlen($s2)) $s2 = str_pad($s2, $l1, $s2, STR_PAD_RIGHT);
    return base64_encode($s1 ^ $s2);
}

$Skey = "password";
$para1 = $_POST["para1"];

$result = llXorBase64($para1, base64_encode($Skey));

echo "Encrypted Data: ".$para1.PHP_EOL;
echo "Unencrypted ".base64_decode($result);

?>

Java でのデコード方法

BASE64 ハッシュを GET 経由で転送する場合は、必ず URLEncode を行ってください。


       String BASE64datahash = "error";
       String passhash = "error";

       try {
        //URLDecode the URL encoded encrypted data
        BASE64datahash = java.net.URLDecoder.decode("KhoFRRYaAUMbEVU%3D", "UTF-8"); //KhoFRRYaAUMbEVU%3D
        System.out.println("BASE64datahash: " + BASE64datahash); //KhoFRRYaAUMbEVU=

        //create an array of BASE64 data
        char[] BASE64data = BASE64datahash.toCharArray();
        char[] dataUB = new String(new BASE64Decoder().decodeBuffer(new String(BASE64data))).toCharArray(); //BASE64 decode the data
        System.out.println("encrypted data (but base64 decoded) [dataUB]: " + new String(dataUB));


        //Encode the secred key/password to BASE64 (Just to show how to use BASE64Encoder)
        //String BASE64password = new String(new BASE64Encoder().encodeBuffer("supersecretpassword".getBytes()));
        //System.out.println("BASE64password: " + new String(BASE64password));

        //create array of BASE64 key/password
        //char[] key = BASE64password.toCharArray();
        //char[] keyUB = new String(new BASE64Decoder().decodeBuffer(new String(key))).toCharArray();
        char[] keyUB = "supersecretpassword".toCharArray(); 
        System.out.println("plaintext key/password [keyUB]: " + new String(keyUB));

        //XOR data array chars with corresponding key/password array chars
        int k=0;
        for (int i = 0; i < dataUB.length; i++) {
            dataUB[i] = (char) (dataUB[i] ^ keyUB[k]);
            k++;

            //Loop to start of the key if the key is too short
            if (k == keyUB.length)
               k=0;
		}

        System.out.println("Decoded data [dataUB]: " + new String(dataUB));
        
        } catch (Exception ex) {
            System.out.println("Oops!");
        }

特記事項

All Issues

~ Search JIRA for related Issues
   llXorBase64StringsCorrect zero out last (bitcount % 8) bits of data.
   llXorBase64StringsCorrect returns wrong result when the 2nd string contains nulls
   llXorBase64 returns wrong result after second str2 repeat

Signature

function string llXorBase64( string str1, string str2 );
この翻訳は 原文 と比べて古いですか?間違いがありますか?読みにくいですか?みんなで 修正 していきましょう! (手順はこちら)
この項目はあなたにとって参考にならない項目ですか?もしかしたらLSL Wikiの関連した項目が参考になるかもしれません。