web-dev-qa-db-ja.com

同じキーで暗号化された同じ文字列は、同じ暗号化された値を生成しませんか?

これは、データベースに入力および保存された文字列を暗号化するための私のページとクラスです。毎回、Key__cはカスタム設定から取得したものと同じです。しかし、abcと入力して2回保存すると、入力した値が異なります。理由は何ですか?

<apex:page controller="encryptNewController">
    <apex:form >   
         <apex:outPutLabel value="Encrypted by Code"/>
         <apex:inputsecret value="{!encryptedByCode}"/>


         <apex:commandButton value="Save" action="{!saveValues}"/>
         <apex:outputText value="{!decryptedDataString}"/>
    </apex:form>
</apex:page>


public with sharing class encryptNewController {

     Public Encrypt_Object__c encryptObject {get;set;}
     Public String encryptedByCode {get;set;}
     Public String decryptedDataString {get;set;}
     Blob cryptoKey;
     public encryptNewController(){
          encryptObject=new Encrypt_Object__c();
     }
     public void saveValues(){
            List<CryptoKey__c> keyValue = [SELECT  Key__c FROM CryptoKey__c where id != null];
                String cryptoKeyString;
                System.debug('000000000000000000000000000000000000000000keyValue'+keyValue);
                if(keyValue.size() > 0){
                    cryptoKeyString = keyValue[0].Key__c;
                    cryptoKey = EncodingUtil.base64Decode(cryptoKeyString);
                System.debug('000000000000000000000000000000000000000000cryptoKey'+cryptoKey);
            }           
            encryptObject.Encrypted_by_Code__c = encryptToken(encryptedByCode);

            insert encryptObject;
            Encrypt_Object__c insertedencryptObject = [Select id,Encrypted_by_Code__c from Encrypt_Object__c where id=: encryptObject.id][0];
            decryptedDataString =decryptToken(insertedencryptObject.Encrypted_by_Code__c);            
     }

     public String encryptToken(String strOriginal){
        Blob encryptedData;
        if(cryptoKey != null){
            String strUrlUTF8 = EncodingUtil.urlEncode(strOriginal, 'UTF-8');
            Blob b = Blob.valueOf(strUrlUTF8);
            System.debug('@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@cryptoKey'+cryptoKey);
            encryptedData = Crypto.encryptWithManagedIV('AES256', cryptoKey, b);
            return  EncodingUtil.base64Encode(encryptedData);
        }else{
            return null;
        }

      }

      public String decryptToken(String encryptedString){
        if(cryptoKey != null){
         Blob b = EncodingUtil.base64Decode(encryptedString);
         Blob decryptedData = Crypto.decryptWithManagedIV('AES256', cryptoKey, b);
         String strUrlUTF8 = decryptedData.toString();
         return EncodingUtil.urlDecode(strUrlUTF8, 'UTF-8');
        }else{
            return null;
        }
      }   
}
================================================

同じキーで暗号化された同じ文字列は、同じ暗号化された値を生成しませんか?

7
jyothy

ほとんどの暗号化スキームは、同じ値を2回暗号化すると異なる暗号化値が生成されるように設計されています。これはセキュリティプロパティです。

同じ値を2回暗号化すると同じ暗号文が得られるような暗号化スキームは、確定的であると言われています。一部のアプリケーションでは確定的暗号化が必要ですが、デフォルトでは回避する必要があります。

次のシナリオを考えてみましょう。サーバーは、ドキュメントをアップロードして暗号化することを許可しますが、ドキュメントの復号化は許可しません。他の人のドキュメントの内容を知りたいとしましょう。私はいくつかの推測を行い、それらをサーバーに送信して、自分の推測に対応する暗号文を取得します。暗号化スキームが確定的である場合、私の推測の暗号文を機密文書の暗号文と比較できます。ランダム要素を含む暗号化スキームを使用すると、私の推測が正しい場合でも、暗号文は異なります。したがって、ランダム化された暗号化スキームは セマンティックセキュリティ を提供できますが、確定的スキームは提供できません。

ほとんどの対称暗号化スキームには、暗号化が実行されるたびに 初期化ベクトル (IV)または他の要素が含まれます(多くの場合ランダムですが、要件はアルゴリズムによって異なります)。多くの非対称暗号化スキームには、ランダムな パディング が含まれ、同じ効果が得られます。

したがって、同じ値を2回暗号化すると異なる結果が生成されるのは正常です。実際、確定的暗号化の必要性を確立していない限り、同じ値を2回取得することは、何かが間違っていることを示しています。アプリケーションをテストしている場合、既知の値に対して暗号文をテストすることはできません。個別に復号化する必要があります。

encryptWithManagedIV ()は、使用するたびにランダムなIVを生成するようです。したがって、さまざまな暗号文(良いBTWです)。 ここ を参照してください:

EncryptWithManagedIV()関数を使用して、暗号化テキストの最初の16バイトでIVを生成するようSalesforceに設定します。

2
Andrey