使用相同密钥加密的相同字符串不会生成相同的加密值吗?

信息安全 加密 爪哇
2021-08-30 03:57:37

这是我的页面和类,用于加密输入并保存在数据库中的字符串。每次Key__c都是一样的,因为我是从自定义设置中获取的。但是当我输入abc并保存两次时,输入的值是不同的。是什么原因?

<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;
        }
      }   
}
================================================

使用相同密钥加密的相同字符串不会生成相同的加密值吗?

2个回答

大多数加密方案被设计成对相同的值加密两次会生成不同的加密值。这是一个安全属性。

将相同值加密两次导致相同密文的加密方案被称为确定性的。在某些应用程序中需要确定性加密,但默认情况下应避免使用。

考虑以下场景:服务器愿意让我上传文档并加密它们,但不让我解密文档。假设我想知道别人文档的内容。我做了一些猜测并将它们提交给服务器,我得到了与我的猜测相对应的密文。如果加密方案是确定性的,那么我可以将我猜测的密文与机密文档的密文进行比较。使用包含随机元素的加密方案,即使我的猜测是正确的,密文也会有所不同——因此随机加密方案可以提供语义安全,但确定性方案不能。

大多数对称加密方案包括一个初始化向量(IV) 或其他不同的元素(通常是随机的,但要求因算法而异),每次执行加密时。许多非对称加密方案包括随机填充以获得相同的效果。

因此,两次加密相同的值会产生不同的结果是正常的。事实上,除非您确定需要确定性加密,否则两次获得相同的值将表明出现问题。如果您正在测试您的应用程序,则无法针对已知值测试密文,您需要独立解密它。

似乎encryptWithManagedIV ()每次使用它都会生成随机 IV。因此,不同的密文(这是很好的顺便说一句)。这里

使用 encryptWithManagedIV() 函数让 Salesforce 在密文的前 16 个字节中为您生成 IV。