重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
DES加密其实都大同小异的。
创新互联建站是一家集网站建设,市北企业网站建设,市北品牌网站建设,网站定制,市北网站建设报价,网络营销,网络优化,市北网站推广为一体的创新建站企业,帮助传统企业提升企业形象加强企业竞争力。可充分满足这一群体相比中小企业更为丰富、高端、多元的互联网需求。同时我们时刻保持专业、时尚、前沿,时刻以成就客户成长自我,坚持不断学习、思考、沉淀、净化自己,让我们为更多的企业打造出实用型网站。
Java里面有人帮我们把这些加密的类都写好了,或者SDK里面自带就有接口可以调。
你看他们demo不一样,是指加密的方式不一样,还是用到的类不一样?
DES安全性相对3DES来说要弱不些,因此现在很多人是在用3DES。
而且密钥的用法也不一样,有些人用固定的密钥,有些人用随机生成的密钥。
楼主把问题描述具体一点吧。
DES是一种对称加密算法,所谓对称加密算法即:加密和解密使用相同密钥的算法。DES加密算法出自IBM的研究,
后来被美国政府正式采用,之后开始广泛流传,但是近些年使用越来越少,因为DES使用56位密钥,以现代计算能力,
24小时内即可被破解
调用过程
最近做微信小程序获取用户绑定的手机号信息解密,试了很多方法。最终虽然没有完全解决,但是也达到我的极限了。有时会报错:javax.crypto.BadPaddingException: pad block corrupted。
出现错误的详细描述
每次刚进入小程序登陆获取手机号时,会出现第一次解密失败,再试一次就成功的问题。如果连续登出,登入,就不会再出现揭秘失败的问题。但是如果停止操作过一会,登出后登入,又会出现第一次揭秘失败,再试一次就成功的问题。
网上说的,官方文档上注意点我都排除了。获取的加密密文是在前端调取wx.login()方法后,调用我后端的微信授权接口,获取用户的sessionkey,openId.然后才是前端调用的获取sessionkey加密的用户手机号接口,所以我可以保证每次sessionkey是最新的。不会过期。
并且我通过日志发现在sessionkey不变的情况下,第一次失败,第二次解密成功。
加密算法,RSA是绕不开的话题,因为RSA算法是目前最流行的公开密钥算法,既能用于加密,也能用户数字签名。不仅在加密货币领域使用,在传统互联网领域的应用也很广泛。从被提出到现在20多年,经历了各种考验,被普遍认为是目前最优秀的公钥方案之一
非对称加密算法的特点就是加密秘钥和解密秘钥不同,秘钥分为公钥和私钥,用私钥加密的明文,只能用公钥解密;用公钥加密的明文,只能用私钥解密。
一、 什么是“素数”?
素数是这样的整数,它除了能表示为它自己和1的乘积以外,不能表示为任何其它两个整数的乘积
二、什么是“互质数”(或“互素数”)?
小学数学教材对互质数是这样定义的:“公约数只有1的两个数,叫做互质数
(1)两个质数一定是互质数。例如,2与7、13与19。
(2)一个质数如果不能整除另一个合数,这两个数为互质数。例如,3与10、5与 26。
(3)1不是质数也不是合数,它和任何一个自然数在一起都是互质数。如1和9908。
(4)相邻的两个自然数是互质数。如 15与 16。
(5)相邻的两个奇数是互质数。如 49与 51。
(6)大数是质数的两个数是互质数。如97与88。
(7)小数是质数,大数不是小数的倍数的两个数是互质数。如 7和 16。
(8)两个数都是合数(二数差又较大),小数所有的质因数,都不是大数的约数,这两个数是互质数。如357与715,357=3×7×17,而3、7和17都不是715的约数,这两个数为互质数。等等。
三、什么是模指数运算?
指数运算谁都懂,不必说了,先说说模运算。模运算是整数运算,有一个整数m,以n为模做模运算,即m mod n。怎样做呢?让m去被n整除,只取所得的余数作为结果,就叫做模运算。例如,10 mod 3=1;26 mod 6=2;28 mod 2 =0等等。
模指数运算就是先做指数运算,取其结果再做模运算。如(5^3) mod 7 = (125 mod 7) = 6。
其中,符号^表示数学上的指数运算;mod表示模运算,即相除取余数。具体算法步骤如下:
(1)选择一对不同的、足够大的素数p,q。
(2)计算n=p q。
(3)计算f(n)=(p-1) (q-1),同时对p, q严加保密,不让任何人知道。
(4)找一个与f(n)互质的数e作为公钥指数,且1ef(n)。
(5)计算私钥指数d,使得d满足(d*e) mod f(n) = 1
(6)公钥KU=(e,n),私钥KR=(d,n)。
(7)加密时,先将明文变换成0至n-1的一个整数M。若明文较长,可先分割成适当的组,然后再进行交换。设密文为C,则加密过程为:C=M^e mod n。
(8)解密过程为:M=C^d mod n。
在RSA密码应用中,公钥KU是被公开的,即e和n的数值可以被第三方窃听者得到。破解RSA密码的问题就是从已知的e和n的数值(n等于pq),想法求出d的数值,这样就可以得到私钥来破解密文。从上文中的公式:(d e) mod ((p-1) (q-1)) = 1,我们可以看出,密码破解的实质问题是:从p q的数值,去求出(p-1)和(q-1)。换句话说,只要求出p和q的值,我们就能求出d的值而得到私钥。
当p和q是一个大素数的时候,从它们的积p q去分解因子p和q,这是一个公认的数学难题。比如当p*q大到1024位时,迄今为止还没有人能够利用任何计算工具去完成分解因子的任务。因此,RSA从提出到现在已近二十年,经历了各种攻击的考验,逐渐为人们接受,普遍认为是目前最优秀的公钥方案之一。
缺点1:虽然RSA的安全性依赖于大数的因子分解,但并没有从理论上证明破译RSA的难度与大数分解难度等价。即RSA的重大缺陷是无法从理论上把握它的保密性能如何。
在android 开发的很多时候。为了保证用户的账户的安全性,再保存用户的密码时,通常会采用MD5加密算法,这种算法是不可逆的,具有一定的安全性
MD5不是加密算法, 因为如果目的是加密,必须满足的一个条件是加密过后可以解密。但是MD5是无法从结果还原出原始数据的。
MD5只是一种哈希算法
#region 跨平台加解密(c# 安卓 IOS)
// public static string sKey = "12345678";
// /// summary
// /// 解密
// /// /summary
// /// param name="pToDecrypt"要解密的以Base64/param
// /// param name="sKey"密钥,且必须为8位/param
// /// returns已解密的字符串/returns
// public static string DesDecrypt(string pToDecrypt)
// {
// //转义特殊字符
// pToDecrypt = pToDecrypt.Replace("-", "+");
// pToDecrypt = pToDecrypt.Replace("_", "/");
// pToDecrypt = pToDecrypt.Replace("~", "=");
// byte[] inputByteArray = Convert.FromBase64String(pToDecrypt);
// using (DESCryptoServiceProvider des = new DESCryptoServiceProvider())
// {
// des.Key = ASCIIEncoding.ASCII.GetBytes(sKey);
// des.IV = ASCIIEncoding.ASCII.GetBytes(sKey);
// System.IO.MemoryStream ms = new System.IO.MemoryStream();
// using (CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write))
// {
// cs.Write(inputByteArray, 0, inputByteArray.Length);
// cs.FlushFinalBlock();
// cs.Close();
// }
// string str = Encoding.UTF8.GetString(ms.ToArray());
// ms.Close();
// return str;
// }
// }
// /// summary
// /// 对字符串进行DES加密
// /// /summary
// /// param name="sourceString"待加密的字符串/param
// /// returns加密后的BASE64编码的字符串/returns
// public string Encrypt(string sourceString)
//{
// byte[] btKey = Encoding.UTF8.GetBytes(sKey);
// byte[] btIV = Encoding.UTF8.GetBytes(sKey);
// DESCryptoServiceProvider des = new DESCryptoServiceProvider();
// using (MemoryStream ms = new MemoryStream())
// {
// byte[] inData = Encoding.UTF8.GetBytes(sourceString);
// try
// {
// using (CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(btKey, btIV), CryptoStreamMode.Write))
// {
// cs.Write(inData, 0, inData.Length);
// cs.FlushFinalBlock();
// }
// return Convert.ToBase64String(ms.ToArray());
// }
// catch
// {
// throw;
// }
// }
//}
#endregion
安卓---------------------------------------------------------------------------
// // 加密
//public static String DecryptDoNet(String message, String key)
// throws Exception {
// byte[] bytesrc = Base64.decode(message.getBytes(), Base64.DEFAULT);
// Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
// DESKeySpec desKeySpec = new DESKeySpec(key.getBytes("UTF-8"));
// SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
// SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
// IvParameterSpec iv = new IvParameterSpec(key.getBytes("UTF-8"));
// cipher.init(Cipher.DECRYPT_MODE, secretKey, iv);
// byte[] retByte = cipher.doFinal(bytesrc);
// return new String(retByte);
//}
//// 解密
//public static String EncryptAsDoNet(String message, String key)
// throws Exception {
// Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
// DESKeySpec desKeySpec = new DESKeySpec(key.getBytes("UTF-8"));
// SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
// SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
// IvParameterSpec iv = new IvParameterSpec(key.getBytes("UTF-8"));
// cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv);
// byte[] encryptbyte = cipher.doFinal(message.getBytes());
// return new String(Base64.encode(encryptbyte, Base64.DEFAULT));
//}
Ios --------------------------------------------------------------------------------------------------------------------\
static const char* encryptWithKeyAndType(const char *text,CCOperation encryptOperation,char *key)
{
NSString *textString=[[NSString alloc]initWithCString:text encoding:NSUTF8StringEncoding];
// NSLog(@"[[item.url description] UTF8String=%@",textString);
const void *dataIn;
size_t dataInLength;
if (encryptOperation == kCCDecrypt)//传递过来的是decrypt 解码
{
//解码 base64
NSData *decryptData = [GTMBase64 decodeData:[textString dataUsingEncoding:NSUTF8StringEncoding]];//转成utf-8并decode
dataInLength = [decryptData length];
dataIn = [decryptData bytes];
}
else //encrypt
{
NSData* encryptData = [textString dataUsingEncoding:NSUTF8StringEncoding];
dataInLength = [encryptData length];
dataIn = (const void *)[encryptData bytes];
}
CCCryptorStatus ccStatus;
uint8_t *dataOut = NULL; //可以理解位type/typedef 的缩写(有效的维护了代码,比如:一个人用int,一个人用long。最好用typedef来定义)
size_t dataOutAvailable = 0; //size_t 是操作符sizeof返回的结果类型
size_t dataOutMoved = 0;
dataOutAvailable = (dataInLength + kCCBlockSizeDES) ~(kCCBlockSizeDES - 1);
dataOut = malloc( dataOutAvailable * sizeof(uint8_t));
memset((void *)dataOut, 00, dataOutAvailable);//将已开辟内存空间buffer的首 1 个字节的值设为值 0
//NSString *initIv = @"12345678";
const void *vkey = key;
const void *iv = (const void *) key; //[initIv UTF8String];
//CCCrypt函数 加密/解密
ccStatus = CCCrypt(encryptOperation,// 加密/解密
kCCAlgorithmDES,// 加密根据哪个标准(des,3des,aes。。。。)
kCCOptionPKCS7Padding,// 选项分组密码算法(des:对每块分组加一次密 3DES:对每块分组加三个不同的密)
vkey, //密钥 加密和解密的密钥必须一致
kCCKeySizeDES,// DES 密钥的大小(kCCKeySizeDES=8)
iv, // 可选的初始矢量
dataIn, // 数据的存储单元
dataInLength,// 数据的大小
(void *)dataOut,// 用于返回数据
dataOutAvailable,
dataOutMoved);
NSString *result = nil;
if (encryptOperation == kCCDecrypt)//encryptOperation==1 解码
{
//得到解密出来的data数据,改变为utf-8的字符串
result = [[NSString alloc] initWithData:[NSData dataWithBytes:(const void *)dataOut length:(NSUInteger)dataOutMoved] encoding:NSUTF8StringEncoding];
}
else //encryptOperation==0 (加密过程中,把加好密的数据转成base64的)
{
//编码 base64
NSData *data = [NSData dataWithBytes:(const void *)dataOut length:(NSUInteger)dataOutMoved];
result = [GTMBase64 stringByEncodingData:data];
}
return [result UTF8String];
}
+(NSString*)encryptWithContent:(NSString*)content type:(CCOperation)type key:(NSString*)aKey
{
const char * contentChar =[content UTF8String];
char * keyChar =(char*)[aKey UTF8String];
const char *miChar;
miChar = encryptWithKeyAndType(contentChar, type, keyChar);
return [NSString stringWithCString:miChar encoding:NSUTF8StringEncoding];
}
Android 自带图标库 android.R.drawable
desandroidstylejavahtmlsrc文件Gocom
在xml文件中调用。
android:title="@string/secure_connect"
android:orderInCategory="100"
android:icon="@android:drawable/ic_menu_search"
android:drawableRight="@android:drawable/arrow_down_float"/
程序中调用。
setIcon(android.R.drawable.stat_notify_error)
Android 自带图标库 android.R.drawable
android des加密其实是可以使用java api自带的算法,例子如下:
通过上面资料的阅读,解决办法就很简单了。
首先在Mainifest.xml的Activity元素中加入android:configChanges="orientation|keyboardHidden"属性
activity android:name=".FileBrowser"
android:label="@string/app_name"
android:configChanges="orientation|keyboardHidden"
intent-filter
action android:name="android.intent.action.MAIN" /
category android:name="android.intent.category.LAUNCHER" /
/intent-filter
/activity
加入这条属性的含义是,应用程序将会处理屏幕方向和键盘状态(推出或合上)信息的改动。但对于其他的设备配置信息的改动则会由Android系统来处理(销毁当前Activity,然后重启一个新的Activity实例)。