java--sha1加密&&元素以字典顺序排序&&微信小程序接入微信公众平台
作者:互联网
java--sha1加密
sha是一种数据加密算法,是目前公认的最安全的散列算法之一,思想是把一段明文以不可逆的方式变成一段密文(把一段称为预映射或信息的输入码变成长度较短位数固定的输出序列即散列值–信息摘要或信息认证代码),散列函数值可以说是对明文的一种指纹或摘要,所以对散列值的数字签名可以视为对此明文的数字签名
安全散列算法sha里规定了sha-1,sha-224,sha-256,sha-384,和sha-512几种单向散列算法,SHA-1,SHA-224和SHA-256适用于长度不超过264二进制位的消息。SHA-384和SHA-512适用于长度不超过2128二进制位的消息。
算法实现
public class SecuritySHA1Utils {
/**
* @Comment SHA1实现
* @Author Ron
* @Date 2017年9月13日 下午3:30:36
* @return
*/
public static String shaEncode(String inStr) throws Exception {
MessageDigest sha = null;//定义一个空的sha密文变量
try {
sha = MessageDigest.getInstance("SHA");//使用MessageDigest.getInstance("SHA")方法得到sha密文实例(表示使用SHA加密方式对明文加密)
} catch (Exception e) {
System.out.println(e.toString());
e.printStackTrace();
return "";
}
byte[] byteArray = inStr.getBytes("UTF-8");//定义一个元素为byte类型的字典,对用户输入的明文先使用getBytes("UTF-8")方法变成utf-8类型的字典
byte[] md5Bytes = sha.digest(byteArray);//再定义一个byte字典,使用sha.digest(byteArray)的方法把字典变成摘要密文字典
StringBuffer hexValue = new StringBuffer();//新建一个new StringBuffer()类型的字符串缓存区变量StringBuffer
for (int i = 0; i < md5Bytes.length; i++) {
int val = ((int) md5Bytes[i]) & 0xff;//遍历密文字典元素,把高24位设置为0避免错误之后如果元素小于16缓存区默认加0,不是就把元素值变成16进制字符串加入缓存区
if (val < 16) {
hexValue.append("0");
}
hexValue.append(Integer.toHexString(val));
}
return hexValue.toString();//
最后把16进制的缓存区内容变成字符串返回
}
public static void main(String args[]) throws Exception {
String str = new String("amigoxiexiexingxing");
System.out.println("原始:" + str);
System.out.println("SHA后:" + shaEncode(str));
}
}
实际的应用中,我们可以直接引入org.apache.commons.codec.digest.DigestUtils,然后按照如下方法调用加密即可。
public static String encodePassword(String psw) {
if(StringUtils.isEmpty(psw)){
return null;
}else{
return DigestUtils.sha1Hex(psw);
}
}
bytes[i] & 0xFF 原理详解
32位电脑里数字以32位存放,所以,一个byte(8位)的数字,对于int这种32位整型,高24位具有随机性(int型的高24位都是不确定的,第8位才是实际数据,所以& 0XFF操作,可以把高24位置0避免把它当成有效位)
https://blog.csdn.net/xuedengyong/article/details/81386225
代码加密的时候经常使用 bytes[i] & 0xFF ,比如
MessageDigest md5 = MessageDigest.getInstance("MD5");
bytes = md5.digest(basestring.toString().getBytes("UTF-8"));
。。。。。。。。。
String hex = Integer.toHexString(bytes[i] & 0xFF);
byte一个字节8位,范围是-128~127
计算机里负数的存储的值是它的补码,-128是1000 0000取反0111 1111加一=1000 0000,-1是0000 0001取反加一 1111 1111(255)
所以-128-1对应的是128255
以字典顺序排序
https://blog.csdn.net/qq_27292113/article/details/79610729
private static void SortList() {
ArrayList<String> arl = new ArrayList<String>();
arl.add("D");
arl.add("a");
arl.add("E");
arl.add("A");
arl.add("张三");
Collections.sort(arl, new Comparator<String>() {
public int compare(String o1, String o2) {
try {
// 取得比较对象的汉字编码,并将其转换成字符串
String s1 = new String(o1.toString().getBytes("GB2312"), "ISO-8859-1");
String s2 = new String(o2.toString().getBytes("GB2312"), "ISO-8859-1");
// 运用String类的 compareTo()方法对两对象进行比较
return s1.compareTo(s2);
} catch (Exception e) {
e.printStackTrace();
}
return 0;
}
});// 根据元素的自然顺序 对指定列表按升序进行排序。
for (int i = 0; i < arl.size(); i++) {
System.out.println(arl.get(i));
}
php----$_GET[]
$_GET[]是php的一个内置全局服务器变量。一个请求中的所有get参数都会存储在KaTeX parse error: Expected 'EOF', got '&' at position 33: …st?search=apple&̲a=valuea 则在php中…GET变量为一个数组,数组的索引为请求参数的key,数组的值为请求参数key对应的value。
因此:$_GET[‘search’]=‘apple’;$_GET[‘a’]=‘valuea’;
http认证中的nonce与timestamp
nonce是服务器生成的一个随机数,在客户端第一次请求页面的时候把它发挥客户端,客户把从服务器得到的它和用户密码串联到一起进行不可逆加密(MD5、SHA1等等),之后把这个加密后的字符串和用户名,nonce,加密算法名称后发给服务器,之后服务器用用户名搜到密码之后使用同样的算法进行加密,然后比较,每个nonce只能让一个用户使用一次,有效避免攻击,还可以发现恶意请求,由于数据库里的nonce随机数不多所以可能不够用,所以会加上时间戳timestamp
随着用户访问的增加,数据库中保存的nonce/timestamp/username数据量会变得非常大。对于这个问题,可选的解决方案是对数据设定一个“过期时间”,比如说在数据库中保存超过一天的数据将会被清除。比如说将时间戳与服务器当前时间比较,如果相差一天则认为该时间戳是无效的。
token和nonce区别
token也是需要设置一个有效期的,否则其他人只要登录过一次就可以永远地通过 API 的验证。Cookies 基于同样的理由也有一个有效期。
nonce是服务器在用户第一次登录时返回的随机数字
token是开放者自定义的字符串,是服务器段生成的一段字符串,第一次登录之后服务器生成一个token把token给客户端,提交之后token的值会保存到微信后台,所以只有用户的微信后台和服务器知道这个数字,只有用户带上这个token请求数据就不要带上用户名和密码了
微信后台在向公众账号服务器发送数据的时候,会额外带上4个参数:timestamp、signature、nonce、echostr
signature是对timestamp、nonce和Token进行SHA1加密后的字符串
echostr是随机字符串(接入url的时候才有)
微信公众平台的token
是第三方平台(应用)绑定到微信公众好的验证口令,可以由商家自由设置也可以是第三方平台自动生成的,是微信小程序接入微信公众平台服务器需要提供的验证信息
微信接口页面没有做好的话提交保存的时候会提示token验证失败,因为微信app发消息给公众平台的时候需要带上token,平台也需要把token信息返回给app才算接入成功
token使用在微信公众平台-基本配置-服务器配置中,只有商城URL和token配套且和第三方平台上的URL和token一直,才能将微信公众号绑定到第三方平台
PHP implode() 函数
返回由数组元素组成的字符串
implode() 函数接受两种参数顺序。但是由于历史原因,explode() 是不行的,您必须保证 separator 参数在 string 参数之前才行
恶意的第三方有可能会截获微信后台发过来的timestamp、signature和nonce这三个参数,然后直接利用这个三个参数对公众账号服务器发起请求。按照上面的逻辑可以知道,服务器是无法判断出这是个恶意的请求的。这种攻击称为replay攻击。这种攻击方式的防御方法很简单:加上对timestamp的校验。在收到请求之后,将请求包中的timestamp与当前时间比较,如果误差大于一定的值,就可认为这个请求是恶意的。这里不能做相等的比较,因为数据在网络上传输需要时间,同时各个服务的本地时间也是有一些差异的
微信公众号平台Url Token EncodingAESKey
https://www.cnblogs.com/blogtech/p/10877492.html
微信公众号回复一些用户的私密信息的时候需要对信息加密
用于加密发送的消息,选择方式之后会自动生成,可以用微信直接关联自己做的网站,自己不会开放的话可以关联一些第三方系统
可以新增消息提的签名认证
可以给推送给微信公众号的消息进行加密
公众号对于密文消息的回复也需要加密
启用加解密功能(兼容模式或安全模式之后),公众平台服务器会在想公众帐号的服务器配置的地址(可在“开发者中心”修改)推送消息时,URL将新增加两个参数(加密类型和消息体签名),并以此来体现新功能,加密算法采用AES,具体的加解密流程和方案请看接入指引、技术方案和示例代码。
为了配合消息加密功能的上线,并帮助开发者适配新特性,公众平台提供了3种加解密的模式供开发者选择,即明文模式、兼容模式、安全模式(可在“开发者中心”选择相应模式),选择兼容模式和安全模式前,需在开发者中心填写消息加解密密钥EncodingAESKey。
明文模式,消息明文收发
兼容模式公众平台发送的消息同时包括明文和密文,公众号可以回复明文或密文,不影响现有消息的收发,开发者可在此模式下进行调试
安全模式,公众平台发送的消息提只有密文,公共帐号回复的消息体也是密文,建议开发者在调试成功后使用此模式收发消息
微信公众平台采用AES对称加密算法对推送给公众帐号的消息体对行加密,EncodingAESKey则是加密所用的秘钥。公众帐号用此秘钥对收到的密文消息体进行解密,回复消息体也用此秘钥加密
url是开发者用于接收微信消息和时间的借口,token可以由开发者任意填写,用于生成签名(token会配置在服务器里与url发送的进行比较)EncodingAESKey由开发者手动填写或随机生成,将用作消息体加解密密钥
Token EncodingAESKey 需要配置在你的服务器中 WxMpService 的 Config 中,此时还需要编写微信服务访问你接口的代码,返回微信服务器需要返回的结果才会提交成功(Token验证失效,URL超时之类,基本问题都是点击提交按钮,微信会自动访问你配置的接口不能返回微信所需要的结果)
https://www.cnblogs.com/blogtech/p/10877492.html
php检验微信signature
获取用户发过来的签名和时间戳和nonce信息之后存成变量
把token存成变量,把时间戳,token和nonce存成一个字典之后使用sort对字典元素进行排序
之后使用implode方法返回字典元素组成的字符串,使用sha1对字符串进行加密
微信公众号服务器配置
标签:nonce,sha1,加密,微信,公众,token,&&,服务器 来源: https://blog.csdn.net/weixin_46045444/article/details/120604037