之前在項(xiàng)目上用到AES256加密解密算法,剛開(kāi)始在java端加密解密都沒(méi)有問(wèn)題,在iOS端加密解密也沒(méi)有問(wèn)題。但是奇怪的是在java端加密后的文件在iOS端無(wú)法正確解密打開(kāi),然后簡(jiǎn)單測(cè)試了一下,發(fā)現(xiàn)在java端和iOS端采用相同明文,相同密鑰加密后的密文不一樣!上網(wǎng)查了資料后發(fā)現(xiàn)iOS中AES加密算法采用的填充是PKCS7Padding,而java不支持PKCS7Padding,只支持PKCS5Padding。我們知道加密算法由算法+模式+填充組成,所以這兩者不同的填充算法導(dǎo)致相同明文相同密鑰加密后出現(xiàn)密文不一致的情況。那么我們需要在java中用PKCS7Padding來(lái)填充,這樣就可以和iOS端填充算法一致了。
成都創(chuàng)新互聯(lián)公司-專業(yè)網(wǎng)站定制、快速模板網(wǎng)站建設(shè)、高性價(jià)比紫金網(wǎng)站開(kāi)發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫(kù),直接使用。一站式紫金網(wǎng)站制作公司更省心,省錢(qián),快速模板網(wǎng)站建設(shè)找我們,業(yè)務(wù)覆蓋紫金地區(qū)。費(fèi)用合理售后完善,10年實(shí)體公司更值得信賴。
要實(shí)現(xiàn)在java端用PKCS7Padding填充,需要用到bouncycastle組件來(lái)實(shí)現(xiàn),下面我會(huì)提供該包的下載。啰嗦了一大堆,下面是一個(gè)簡(jiǎn)單的測(cè)試,上代碼!
001 package com.encrypt.file;
002
003
004 import java.io.UnsupportedEncodingException;
005 importjava.security.Key;
006 import java.security.Security;
007
008 importjavax.crypto.Cipher;
009 importjavax.crypto.SecretKey;
010 importjavax.crypto.spec.SecretKeySpec;
011
012 public classAES256Encryption{
013
014 /**
015 * 密鑰算法
016 * java6支持56位密鑰,bouncycastle支持64位
017 * */
018 public static finalString KEY_ALGORITHM="AES";
019
020 /**
021 * 加密/解密算法/工作模式/填充方式
022 *
023 * JAVA6 支持PKCS5PADDING填充方式
024 * Bouncy castle支持PKCS7Padding填充方式
025 * */
026 public static finalString CIPHER_ALGORITHM="AES/ECB/PKCS7Padding";
027
028 /**
029 *
030 * 生成密鑰,java6只支持56位密鑰,bouncycastle支持64位密鑰
031 * @return byte[] 二進(jìn)制密鑰
032 * */
033 public static byte[] initkey() throwsException{
034
035 // //實(shí)例化密鑰生成器
036 // Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
037 // KeyGenerator kg=KeyGenerator.getInstance(KEY_ALGORITHM, "BC");
038 // //初始化密鑰生成器,AES要求密鑰長(zhǎng)度為128位、192位、256位
039 //// kg.init(256);
040 // kg.init(128);
041 // //生成密鑰
042 // SecretKey secretKey=kg.generateKey();
043 // //獲取二進(jìn)制密鑰編碼形式
044 // return secretKey.getEncoded();
045 //為了便于測(cè)試,這里我把key寫(xiě)死了,如果大家需要自動(dòng)生成,可用上面注釋掉的代碼
046 return new byte[] { 0x08, 0x08, 0x04, 0x0b, 0x02, 0x0f, 0x0b, 0x0c,
047 0x01, 0x03, 0x09, 0x07, 0x0c, 0x03, 0x07, 0x0a, 0x04, 0x0f,
048 0x06, 0x0f, 0x0e, 0x09, 0x05, 0x01, 0x0a, 0x0a, 0x01, 0x09,
049 0x06, 0x07, 0x09, 0x0d };
050 }
051
052 /**
053 * 轉(zhuǎn)換密鑰
054 * @param key 二進(jìn)制密鑰
055 * @return Key 密鑰
056 * */
057 public static Key toKey(byte[] key) throwsException{
058 //實(shí)例化DES密鑰
059 //生成密鑰
060 SecretKey secretKey=newSecretKeySpec(key,KEY_ALGORITHM);
061 returnsecretKey;
062 }
063
064 /**
065 * 加密數(shù)據(jù)
066 * @param data 待加密數(shù)據(jù)
067 * @param key 密鑰
068 * @return byte[] 加密后的數(shù)據(jù)
069 * */
070 public static byte[] encrypt(byte[] data,byte[] key) throwsException{
071 //還原密鑰
072 Key k=toKey(key);
073 /**
074 * 實(shí)例化
075 * 使用 PKCS7PADDING 填充方式,按如下方式實(shí)現(xiàn),就是調(diào)用bouncycastle組件實(shí)現(xiàn)
076 * Cipher.getInstance(CIPHER_ALGORITHM,"BC")
077 */
078 Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
079 Cipher cipher=Cipher.getInstance(CIPHER_ALGORITHM, "BC");
080 //初始化,設(shè)置為加密模式
081 cipher.init(Cipher.ENCRYPT_MODE, k);
082 //執(zhí)行操作
083 returncipher.doFinal(data);
084 }
085 /**
086 * 解密數(shù)據(jù)
087 * @param data 待解密數(shù)據(jù)
088 * @param key 密鑰
089 * @return byte[] 解密后的數(shù)據(jù)
090 * */
091 public static byte[] decrypt(byte[] data,byte[] key) throwsException{
092 //歡迎密鑰
093 Key k =toKey(key);
094 /**
095 * 實(shí)例化
096 * 使用 PKCS7PADDING 填充方式,按如下方式實(shí)現(xiàn),就是調(diào)用bouncycastle組件實(shí)現(xiàn)
097 * Cipher.getInstance(CIPHER_ALGORITHM,"BC")
098 */
099 Cipher cipher=Cipher.getInstance(CIPHER_ALGORITHM);
100 //初始化,設(shè)置為解密模式
101 cipher.init(Cipher.DECRYPT_MODE, k);
102 //執(zhí)行操作
103 returncipher.doFinal(data);
104 }
105 /**
106 * @param args
107 * @throws UnsupportedEncodingException
108 * @throws Exception
109 */
110 public static void main(String[] args) throwsUnsupportedEncodingException{
111
112 String str="AES";
113 System.out.println("原文:"+str);
114
115 //初始化密鑰
116 byte[] key;
117 try {
118 key = AES256Encryption.initkey();
119 System.out.print("密鑰:");
120 for(int i = 0;ikey.length;i++){
121 System.out.printf("%x", key[i]);
122 }
123 System.out.print("\n");
124 //加密數(shù)據(jù)
125 byte[] data=AES256Encryption.encrypt(str.getBytes(), key);
126 System.out.print("加密后:");
127 for(int i = 0;idata.length;i++){
128 System.out.printf("%x", data[i]);
129 }
130 System.out.print("\n");
131
132 //解密數(shù)據(jù)
133 data=AES256Encryption.decrypt(data, key);
134 System.out.println("解密后:"+newString(data));
135 } catch (Exception e) {
136 // TODO Auto-generated catch block
137 e.printStackTrace();
138 }
139
140 }
141 }
運(yùn)行程序后的結(jié)果截圖:
ViewController.m文件
01 //
02 // ViewController.m
03 // AES256EncryptionDemo
04 //
05 // Created by 孫 裔 on 12-12-13.
06 // Copyright (c) 2012年 rich sun. All rights reserved.
07 //
08
09 #import "ViewController.h"
10 #import "EncryptAndDecrypt.h"
11
12 @interface ViewController ()
13
14 @end
15
16 @implementation ViewController
17 @synthesize plainTextField;
18 - (void)viewDidLoad
19 {
20 [super viewDidLoad];
21 // Do any additional setup after loading the view, typically from a nib.
22 }
23
24 - (void)didReceiveMemoryWarning
25 {
26 [super didReceiveMemoryWarning];
27 // Dispose of any resources that can be recreated.
28 }
29 //這個(gè)函數(shù)實(shí)現(xiàn)了用戶輸入完后點(diǎn)擊視圖背景,關(guān)閉鍵盤(pán)
30 - (IBAction)backgroundTap:(id)sender{
31 [plainTextField resignFirstResponder];
32 }
33
34 - (IBAction)encrypt:(id)sender {
35
36 NSString *plainText = plainTextField.text;//明文
37 NSData *plainTextData = [plainText dataUsingEncoding:NSUTF8StringEncoding];
38
39 //為了測(cè)試,這里先把密鑰寫(xiě)死
40 Byte keyByte[] = {0x08,0x08,0x04,0x0b,0x02,0x0f,0x0b,0x0c,0x01,0x03,0x09,0x07,0x0c,0x03,
41 0x07,0x0a,0x04,0x0f,0x06,0x0f,0x0e,0x09,0x05,0x01,0x0a,0x0a,0x01,0x09,
42 0x06,0x07,0x09,0x0d};
43 //byte轉(zhuǎn)換為NSData類型,以便下邊加密方法的調(diào)用
44 NSData *keyData = [[NSData alloc] initWithBytes:keyByte length:32];
45 //
46 NSData *cipherTextData = [plainTextData AES256EncryptWithKey:keyData];
47 Byte *plainTextByte = (Byte *)[cipherTextData bytes];
48 for(int i=0;i[cipherTextData length];i++){
49 printf("%x",plainTextByte[i]);
50 }
51
52 }
53 @end
DES是一種對(duì)稱加密算法,所謂對(duì)稱加密算法即:加密和解密使用相同密鑰的算法。DES加密算法出自IBM的研究,
后來(lái)被美國(guó)政府正式采用,之后開(kāi)始廣泛流傳,但是近些年使用越來(lái)越少,因?yàn)镈ES使用56位密鑰,以現(xiàn)代計(jì)算能力,
24小時(shí)內(nèi)即可被破解
調(diào)用過(guò)程
最近做微信小程序獲取用戶綁定的手機(jī)號(hào)信息解密,試了很多方法。最終雖然沒(méi)有完全解決,但是也達(dá)到我的極限了。有時(shí)會(huì)報(bào)錯(cuò):javax.crypto.BadPaddingException: pad block corrupted。
出現(xiàn)錯(cuò)誤的詳細(xì)描述
每次剛進(jìn)入小程序登陸獲取手機(jī)號(hào)時(shí),會(huì)出現(xiàn)第一次解密失敗,再試一次就成功的問(wèn)題。如果連續(xù)登出,登入,就不會(huì)再出現(xiàn)揭秘失敗的問(wèn)題。但是如果停止操作過(guò)一會(huì),登出后登入,又會(huì)出現(xiàn)第一次揭秘失敗,再試一次就成功的問(wèn)題。
網(wǎng)上說(shuō)的,官方文檔上注意點(diǎn)我都排除了。獲取的加密密文是在前端調(diào)取wx.login()方法后,調(diào)用我后端的微信授權(quán)接口,獲取用戶的sessionkey,openId.然后才是前端調(diào)用的獲取sessionkey加密的用戶手機(jī)號(hào)接口,所以我可以保證每次sessionkey是最新的。不會(huì)過(guò)期。
并且我通過(guò)日志發(fā)現(xiàn)在sessionkey不變的情況下,第一次失敗,第二次解密成功。
加密算法,RSA是繞不開(kāi)的話題,因?yàn)镽SA算法是目前最流行的公開(kāi)密鑰算法,既能用于加密,也能用戶數(shù)字簽名。不僅在加密貨幣領(lǐng)域使用,在傳統(tǒng)互聯(lián)網(wǎng)領(lǐng)域的應(yīng)用也很廣泛。從被提出到現(xiàn)在20多年,經(jīng)歷了各種考驗(yàn),被普遍認(rèn)為是目前最優(yōu)秀的公鑰方案之一
非對(duì)稱加密算法的特點(diǎn)就是加密秘鑰和解密秘鑰不同,秘鑰分為公鑰和私鑰,用私鑰加密的明文,只能用公鑰解密;用公鑰加密的明文,只能用私鑰解密。
一、 什么是“素?cái)?shù)”?
素?cái)?shù)是這樣的整數(shù),它除了能表示為它自己和1的乘積以外,不能表示為任何其它兩個(gè)整數(shù)的乘積
二、什么是“互質(zhì)數(shù)”(或“互素?cái)?shù)”)?
小學(xué)數(shù)學(xué)教材對(duì)互質(zhì)數(shù)是這樣定義的:“公約數(shù)只有1的兩個(gè)數(shù),叫做互質(zhì)數(shù)
(1)兩個(gè)質(zhì)數(shù)一定是互質(zhì)數(shù)。例如,2與7、13與19。
(2)一個(gè)質(zhì)數(shù)如果不能整除另一個(gè)合數(shù),這兩個(gè)數(shù)為互質(zhì)數(shù)。例如,3與10、5與 26。
(3)1不是質(zhì)數(shù)也不是合數(shù),它和任何一個(gè)自然數(shù)在一起都是互質(zhì)數(shù)。如1和9908。
(4)相鄰的兩個(gè)自然數(shù)是互質(zhì)數(shù)。如 15與 16。
(5)相鄰的兩個(gè)奇數(shù)是互質(zhì)數(shù)。如 49與 51。
(6)大數(shù)是質(zhì)數(shù)的兩個(gè)數(shù)是互質(zhì)數(shù)。如97與88。
(7)小數(shù)是質(zhì)數(shù),大數(shù)不是小數(shù)的倍數(shù)的兩個(gè)數(shù)是互質(zhì)數(shù)。如 7和 16。
(8)兩個(gè)數(shù)都是合數(shù)(二數(shù)差又較大),小數(shù)所有的質(zhì)因數(shù),都不是大數(shù)的約數(shù),這兩個(gè)數(shù)是互質(zhì)數(shù)。如357與715,357=3×7×17,而3、7和17都不是715的約數(shù),這兩個(gè)數(shù)為互質(zhì)數(shù)。等等。
三、什么是模指數(shù)運(yùn)算?
指數(shù)運(yùn)算誰(shuí)都懂,不必說(shuō)了,先說(shuō)說(shuō)模運(yùn)算。模運(yùn)算是整數(shù)運(yùn)算,有一個(gè)整數(shù)m,以n為模做模運(yùn)算,即m mod n。怎樣做呢?讓m去被n整除,只取所得的余數(shù)作為結(jié)果,就叫做模運(yùn)算。例如,10 mod 3=1;26 mod 6=2;28 mod 2 =0等等。
模指數(shù)運(yùn)算就是先做指數(shù)運(yùn)算,取其結(jié)果再做模運(yùn)算。如(5^3) mod 7 = (125 mod 7) = 6。
其中,符號(hào)^表示數(shù)學(xué)上的指數(shù)運(yùn)算;mod表示模運(yùn)算,即相除取余數(shù)。具體算法步驟如下:
(1)選擇一對(duì)不同的、足夠大的素?cái)?shù)p,q。
(2)計(jì)算n=p q。
(3)計(jì)算f(n)=(p-1) (q-1),同時(shí)對(duì)p, q嚴(yán)加保密,不讓任何人知道。
(4)找一個(gè)與f(n)互質(zhì)的數(shù)e作為公鑰指數(shù),且1ef(n)。
(5)計(jì)算私鑰指數(shù)d,使得d滿足(d*e) mod f(n) = 1
(6)公鑰KU=(e,n),私鑰KR=(d,n)。
(7)加密時(shí),先將明文變換成0至n-1的一個(gè)整數(shù)M。若明文較長(zhǎng),可先分割成適當(dāng)?shù)慕M,然后再進(jìn)行交換。設(shè)密文為C,則加密過(guò)程為:C=M^e mod n。
(8)解密過(guò)程為:M=C^d mod n。
在RSA密碼應(yīng)用中,公鑰KU是被公開(kāi)的,即e和n的數(shù)值可以被第三方竊聽(tīng)者得到。破解RSA密碼的問(wèn)題就是從已知的e和n的數(shù)值(n等于pq),想法求出d的數(shù)值,這樣就可以得到私鑰來(lái)破解密文。從上文中的公式:(d e) mod ((p-1) (q-1)) = 1,我們可以看出,密碼破解的實(shí)質(zhì)問(wèn)題是:從p q的數(shù)值,去求出(p-1)和(q-1)。換句話說(shuō),只要求出p和q的值,我們就能求出d的值而得到私鑰。
當(dāng)p和q是一個(gè)大素?cái)?shù)的時(shí)候,從它們的積p q去分解因子p和q,這是一個(gè)公認(rèn)的數(shù)學(xué)難題。比如當(dāng)p*q大到1024位時(shí),迄今為止還沒(méi)有人能夠利用任何計(jì)算工具去完成分解因子的任務(wù)。因此,RSA從提出到現(xiàn)在已近二十年,經(jīng)歷了各種攻擊的考驗(yàn),逐漸為人們接受,普遍認(rèn)為是目前最優(yōu)秀的公鑰方案之一。
缺點(diǎn)1:雖然RSA的安全性依賴于大數(shù)的因子分解,但并沒(méi)有從理論上證明破譯RSA的難度與大數(shù)分解難度等價(jià)。即RSA的重大缺陷是無(wú)法從理論上把握它的保密性能如何。
在android 開(kāi)發(fā)的很多時(shí)候。為了保證用戶的賬戶的安全性,再保存用戶的密碼時(shí),通常會(huì)采用MD5加密算法,這種算法是不可逆的,具有一定的安全性
MD5不是加密算法, 因?yàn)槿绻康氖羌用?,必須滿足的一個(gè)條件是加密過(guò)后可以解密。但是MD5是無(wú)法從結(jié)果還原出原始數(shù)據(jù)的。
MD5只是一種哈希算法
您好!
可能是您輸入的WiFi密碼沒(méi)有達(dá)到8位數(shù),所以顯示的是灰色的哦。
如果有任何問(wèn)題可以隨時(shí)來(lái)咨詢我們的。非常感謝您對(duì)我們vivo的支持,祝您生活愉快!
AES加密過(guò)程涉及到 4 種操作,分別是字節(jié)替代、行移位、列混淆和輪密鑰加。
1.字節(jié)替換:字節(jié)代替的主要功能是通過(guò)S盒完成一個(gè)字節(jié)到另外一個(gè)字節(jié)的映射。
2.行移位:行移位的功能是實(shí)現(xiàn)一個(gè)4x4矩陣內(nèi)部字節(jié)之間的置換。
4.輪密鑰加:加密過(guò)程中,每輪的輸入與輪密鑰異或一次(當(dāng)前分組和擴(kuò)展密鑰的一部分進(jìn)行按位異或);因?yàn)槎M(jìn)制數(shù)連續(xù)異或一個(gè)數(shù)結(jié)果是不變的,所以在解密時(shí)再異或上該輪的密鑰即可恢復(fù)輸入。
5.密鑰擴(kuò)展:其復(fù)雜性是確保算法安全性的重要部分。當(dāng)分組長(zhǎng)度和密鑰長(zhǎng)度都是128位時(shí),AES的加密算法共迭代10輪,需要10個(gè)子密鑰。AES的密鑰擴(kuò)展的目的是將輸入的128位密鑰擴(kuò)展成11個(gè)128位的子密鑰。AES的密鑰擴(kuò)展算法是以字為一個(gè)基本單位(一個(gè)字為4個(gè)字節(jié)),剛好是密鑰矩陣的一列。因此4個(gè)字(128位)密鑰需要擴(kuò)展成11個(gè)子密鑰,共44個(gè)字。
你沒(méi)有指定RNG的Provider
未指定的情況下 Android 2.3以上版本使用的是 隨機(jī)數(shù)序列是 Android's OpenSSL-backed security provider
以下版本是 BouncyCastle Security Provider
JDK 1.7內(nèi)沒(méi)有這個(gè)Provider, 這個(gè)Android自己搞的,你服務(wù)端一定解不出來(lái)的。
目前Android支持的 RNG有以下幾種
Android's OpenSSL-backed security provider 1ASN.1, DER, PkiPath, PKCS7
BouncyCastle Security Provider v1.49 HARMONY (SHA1 digest; SecureRandom; SHA1withDSA signature) Harmony JSSE Provider Android KeyStore security provider
服務(wù)端如果也沒(méi)指定的話,默認(rèn)使用的是
SUN (DSA key/parameter generation; DSA signing; SHA-1, MD5 digests; SecureRandom; X.509 certificates; JKS keystore; PKIX CertPathValidator; PKIX CertPathBuilder; LDAP, Collection CertStores, JavaPolicy Policy; JavaLoginConfig Configuration)
Oracle JDK 1.7 環(huán)境下 支持以下
SUN (DSA key/parameter generation; DSA signing; SHA-1, MD5 digests; SecureRandom; X.509 certificates; JKS keystore; PKIX CertPathValidator; PKIX CertPathBuilder; LDAP, Collection CertStores, JavaPolicy Policy; JavaLoginConfig Configuration)
Sun RSA signature provider
Sun Elliptic Curve provider (EC, ECDSA, ECDH)
Sun JSSE provider(PKCS12, SunX509 key/trust factories, SSLv3, TLSv1)
SunJCE Provider (implements RSA, DES, Triple DES, AES, Blowfish, ARCFOUR, RC2, PBE, Diffie-Hellman, HMAC)
Sun (Kerberos v5, SPNEGO)
Sun SASL provider(implements client mechanisms for: DIGEST-MD5, GSSAPI, EXTERNAL, PLAIN, CRAM-MD5, NTLM; server mechanisms for: DIGEST-MD5, GSSAPI, CRAM-MD5, NTLM)
XMLDSig (DOM XMLSignatureFactory; DOM KeyInfoFactory)
Sun PC/SC provider
Sun's Microsoft Crypto API provider
你們服務(wù)端要是用的 什么 OPENJDK 第三方虛擬機(jī),php什么的話,那就只有天知道支不支持了。
不過(guò)你看也知道了 JDK里的都是SUN自己搞的, Android JVM里掛載的不是Android專用的就是第三方開(kāi)源的,我估計(jì)你是找不到一樣的 隨機(jī)數(shù)生成器 方案了
要具體看加密過(guò)程有沒(méi)有操作失控。
比如補(bǔ)齊方式是不是導(dǎo)致增加。PKCS#5 #7都會(huì)有補(bǔ)齊
比如密文是不是經(jīng)過(guò)BASE64或HEX轉(zhuǎn)過(guò)碼
變成abc12DEB==或FFBB12這種轉(zhuǎn)碼后的碼文,長(zhǎng)度會(huì)相應(yīng)增加一倍或1/3。
具體問(wèn)題具體分析