AES加密解密Windows下跟linux下結果不同的解決方案
現象描述:
在 windows 作業系統下加解密正常,但部署到 linux 環境中相同的輸入加密結果不正確,並且每次執行返回的結果都不同。
原理:
加密過程需手動指定隨機數的生成規則,同理在解密過程中也需手動指定隨機數的生成規則。
java.security.SecureRandom
此類提供加密的強隨機數生成器 (RNG)。許多實現都是偽隨機數生成器 (PRNG) 形式,這意味著它們將使用確定的演算法根據實際的隨機種子生成偽隨機序列。其他實現可以生成實際的隨機數,而另一些實現則可能結合使用這兩項技術。
加密的強隨機數至少要遵從《FIPS 140-2, Security Requirements forCryptographic Modules 》中 4.9.1部分指定的統計隨機數生成器測試。另外,SecureRandom 還必須產生非確定性輸出,因此,正如以下文章中所描述的那樣,要求種子材料必須是不可預知的,SecureRandom 的輸出必須是加密的強序列:《RFC 1750:Randomness Recommendationsfor Security 》。
與 Java Security 中其他基於演算法的類一樣,SecureRandom 也提供了與實現無關的演算法,因此,呼叫方(應用程式程式碼)會請求特定的 RNG 演算法並將它傳回到該演算法的 SecureRandom 物件中。如果需要,還可以通過特定的提供程式請求特定的演算法。請參見 getInstance 方法。
因此,有以下兩種請求 SecureRandom 物件的方法:僅指定演算法名稱,或者既指定演算法名稱又指定包提供程式。
l 如果僅指定演算法名稱,如下所示:
SecureRandomrandom = SecureRandom.getInstance("SHA1PRNG");
系統將確定環境中是否有所請求的演算法實現,是否有多個,是否有首選實現。
l 如果既指定了演算法名稱又指定了包提供程式,如下所示:
SecureRandomrandom = SecureRandom.getInstance("SHA1PRNG", "SUN");
系統將確定在所請求的包中是否有演算法實現;如果沒有,則丟擲異常。
現象描述
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(128, new SecureRandom(key.getBytes()));
修改後程式碼
KeyGenerator kgen = KeyGenerator.getInstance("AES");
SecureRandom random=null;
try {
random = SecureRandom.getInstance("SHA1PRNG","SUN");
} catch (NoSuchProviderException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
random.setSeed(key.getBytes());
kgen.init(128, random);