2

我真的很困惑为什么编码值不同

这是完整的代码

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.security.Key;
import java.security.KeyStore;

import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;

import org.bouncycastle.util.encoders.Base64;

public class KeyStoreDemo {

    private static final String KEY_STORE_TYPE = "JCEKS";
    private static final String KEY_STORE_NAME = "sampleKeyStore.store";
    private static final String KEY_STORE_PASSWORD = "letmein";


    public static void main(String[] args) throws Exception {
        File storeFile = new File(KEY_STORE_NAME);
        storeFile.createNewFile();

        //Create a keystore
        createKeyStore(KEY_STORE_TYPE, storeFile,KEY_STORE_PASSWORD);

        //Generate a key and store it in keystore
        KeyStore keyStore = loadKeyStore(KEY_STORE_TYPE,storeFile,KEY_STORE_PASSWORD);      


        // Get the KeyGenerator     
        KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");keyGenerator.init(128); Key keytemp = keyGenerator.generateKey();       
        System.out.println("key- Base64 before:"+Base64.encode (keytemp.getEncoded()) );
        //createSecretKeyAndStore( keyStore, keytemp, "samplekey" ,"samplepwd");
        createSecretKeyAndStore(storeFile, keyStore, KEY_STORE_PASSWORD, keytemp, "samplekey" ,"samplepwd");

        Key key = getKeyFromStore(keyStore, "samplekey", "samplepwd");
        System.out.println("key- Base64  after :"+Base64.encode (key.getEncoded()) );



    }   

    private static KeyStore createKeyStore(String keyStoreType,File keyStoreFile,String keyStorePassword) throws Exception{     

        KeyStore keyStore = KeyStore.getInstance(keyStoreType);
        keyStore.load((InputStream) null, keyStorePassword.toCharArray());

        // Write KeyStore to disk
        final FileOutputStream fileOutputStream = new FileOutputStream(keyStoreFile);

        try {
            keyStore.store(fileOutputStream, keyStorePassword.toCharArray());
            fileOutputStream.flush();
        } finally {
            fileOutputStream.close();
        }       

        return keyStore;
    }

    private static KeyStore loadKeyStore(String keyStoreType,File keyStoreFile,String keyStorePassword) throws Exception{
        KeyStore keyStore = KeyStore.getInstance(keyStoreType);
        keyStore.load((InputStream) new FileInputStream(keyStoreFile), keyStorePassword.toCharArray());     
        return keyStore;
    }



    private static void createSecretKeyAndStore(File  keyStorefile ,KeyStore keyStore,String keyStorePwd, Key key, String keyAlias ,String keyAccessPassword) throws Exception{
        keyStore.setKeyEntry(keyAlias, key, keyAccessPassword.toCharArray(), null);

        // Write KeyStore to disk
        final FileOutputStream fileOutputStream = new FileOutputStream(keyStorefile);

        try {
            keyStore.store(fileOutputStream, keyStorePwd.toCharArray());
        } finally {
            fileOutputStream.close();
        }
    }




    private static Key getKeyFromStore(KeyStore keyStore, String keyAlias,String keyAccessPassword) throws Exception {
        Key  keyFromStore = null;
        keyFromStore =  keyStore.getKey(keyAlias, keyAccessPassword.toCharArray());
        return keyFromStore;
    }   

}

结果

key- Base64 before:[B@c7e553
key- Base64  after :[B@1ac04e8
4

3 回答 3

6

Base64.encode返回 a char[]- 你得到两个单独的数组这一事实并没有告诉你数组中的值是不同的,只是它们是两个单独的实例。

您需要做的是比较返回的实际数组以检查它们是否包含相同的编码值:

boolean areEqual = Arrays.equals(Base64.encode (keytemp.getEncoded()), 
                                 Base64.encode (key.getEncoded()));
于 2013-03-07T14:02:38.023 回答
2

那是因为,你的印刷品不是什么the Encoded String,它是一个toString value of the char[] array

System.out.println("key-Base64 before:"+new String(Base64.encode(keytemp.getEncoded())));

System.out.println("key-Base64  after :"+new String(Base64.encode(key.getEncoded())) );
于 2013-03-07T17:41:13.793 回答
0

好吧,在我看来,您显示的结果输出不支持您得出的结论。

以下行不打印 key 的 base64 表示:

System.out.println(Base64.encode (key.getEncoded()));

它打印的是对 Base64 转换返回的 byte[] 实例调用 toString() 的结果。在 byte[] 上调用 toString() 根本不会将 byte[] 转换为其字符串表示形式。

因此,您可以从结果中支持的唯一结论是这两个 byte[] 实例不是 JVM 内部的同一个对象实例,考虑到您正在做的事情,这似乎是合理的。

如果您想通过逐字节比较它们的内容来比较 byte[] 实例,您可以使用

Arrays.equals(tempKey.getEncoded(), key.getEncoded())

或者比较编码键的 Base64 :

Arrays.equals(Base64.encode(tempKey.getEncoded()), Base64.encode(key.getEncoded()))

如果要比较字符串表示,则需要将 byte[] 转换为字符串,这很容易看出 base64 仅使用 ASCII 安全值:

String tempKeyEncoded = new String(Base64.encode(tempKey.getEncoded), "US-ASCII");
String keyEncoded = new String(Base64.encode(key.getEncoded), "US-ASCII");
System.out.println(tempKeyEncoded.equals(keyEncoded));

希望这可以帮助。

于 2013-03-07T14:10:51.847 回答