密码学研究-密钥长度限制
引入:
在我們加密解密過程中,因為我上次在維基百科上看到一篇文章http://en.wikipedia.org/wiki/Advanced_Encryption_Standard說,AES的加密方式支持的密鑰是128位,192位和256位 ,而實際應用中,如果我用128位的AES密碼加密,則沒問題:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | public?static?void?main(String[] args)?throws?Exception { ??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ????????//我們演示加密解密字符串 ????????System.out.println("加密解密字符串:"); ??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ????????String stringNeedEncrypt="加密這段文本"; ????????System.out.println("被加密的文本為:"+stringNeedEncrypt); ??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ????????//產生一個密鑰 ????????KeyGenerator keyGen = KeyGenerator.getInstance("AES"); ????????keyGen.init(128); ????????Key key=keyGen.generateKey(); ????????System.out.println("\n加密使用的密鑰為:"+(new?BASE64Encoder()).encode(key.getEncoded())); ????????System.out.println("加密使用的算法為:"+key.getAlgorithm()); ??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ????????//加密字符串過程 ????????System.out.println("\n開始加密字符串..."); ????????byte[] encryptedValue = EncryptUtil.encryptString(stringNeedEncrypt, key); ????????System.out.println("加密后的密文為:"+(new?BASE64Encoder()).encode(encryptedValue)); ??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ????????//解密字符串過程 ????????System.out.println("\n開始解密字符串..."); ????????String decryptedString = EncryptUtil.decryptString(encryptedValue, key); ????????System.out.println("解密后還原的字符串為:"+decryptedString); ????} |
顯示結果為:
但是,如果我們把代碼的第11行 ,keyGen.init改為256(也就是希望密碼長度為256位),那么則會拋出以下的異常:
這是為什么呢?
解決:
這個問題是因為美國在用于加密的密鑰上對于出口做了限制,它不提供很長的,非常高強度的密鑰
因為我們的jdk版本是1.6
所以去http://www.oracle.com/technetwork/java/javase/downloads/jce-6-download-429243.html下載不限制密鑰長度的策略文件。
接受完許可證協議后,下載jce_policy-6.zip文件到本地:
解壓完畢后,吧其中的local_policy.jar和US_export_policy.jar?覆蓋掉%JAVA_HOME%/jre/lib/security目錄下的同名文件:
然后重新運行下我們的應用,就成功了。
分析:
為什么這種方法是可以呢?答案肯定在我們復制的2個jar文件中。
我們先比較下local_policy.jar文件的內容。
對于限制密鑰強度的版本的local_policy.jar文件,在其中default_local.policy文件如下:
此外,還多一個文件叫exempt_local.policy文件,其內容為:
在MANIFEST.MF中,標識出密碼強度(Crypto-Strength)為limited.
對于不限制密鑰強度的版本的local_policy.jar文件,在其中的default_local.policy文件如下:
在MANIFEST.MF中,標識出密碼強度(Crypto-Strength)為unlimited.
我們再比較下US_export_policy.jar文件中的內容:
對于限制密鑰強度的版本的US_export_policy.jar文件,在其中default_local.policy文件如下:
對于非限制密鑰強度的版本的US_export_policy.jar文件,在其中的default_local.policy文件如下:
所以,從上面可以看出,在默認的jdk提供的JCE policy文件和我們單獨下載的無限制密鑰強度的JCE policy文件,對于US_export_policy.jar文件是幾乎完全一樣的。只有local_policy.jar不同。其中默認JDK提供的是有密鑰限制的。
那么這文件怎么讀呢?我們從http://pages.cs.wisc.edu/~horwitz/java-docs/guide/security/jce/JCERefGuide.html中找到了答案。
其中,從最后一個permissionjavax.crypto.CryptoPermisson * ,128條目可以看出,在限制密鑰強度版本,任意算法的密鑰強度最多是128位,這就是為什么我們用128位可以正常工作,但是我們用256位就會報錯。當我們用不受限密鑰強度的local_policy.jar替換的時候,它的permission變成了?permissionjavax.crypto.CryptoAllPermission;?這表明對任意算法,密鑰長度不受限制。
在運行時,當application/applet類通過getInstance()方法實例化Cipher類時,然后如果應用有相關聯的permissionpolicy文件,則JCE?會檢查permission policy?文件是否有一些條目,適用于getInstance()調用中相應的算法。如果有,則進行permission check,放行或者拒絕這次實例化。
本文轉自 charles_wang888 51CTO博客,原文鏈接:http://blog.51cto.com/supercharles888/1317165,如需轉載請自行聯系原作者 與50位技術專家面對面20年技術見證,附贈技術全景圖
總結
以上是生活随笔為你收集整理的密码学研究-密钥长度限制的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 网络部署加实验步骤( 续)
- 下一篇: samba客户端的总结与归纳