java加密算法入门(三)-非对称加密详解
1、简单介绍
这几天一直在看非对称的加密,相比之前的两篇内容,这次看了两倍多的时间还云里雾里的,所以这篇文章相对之前的两篇,概念性的东西多了些,另外是代码的每一步我都做了介绍,方便自己以后翻阅,也方便大家理解。最后就是关于代码的demo,DH算法、RSA算法本文中只有最基础的用法,实际在工作中可能会涉及到密钥的转换X509EncodedKeySpec和PKCS8EncodedKeySpec,相关的demo名分别叫DH2Test,RSA2Test,已经上传GIT。如果对您有帮助,请给我个star。W( ̄_ ̄)W
1.1 什么是非对称加密算法?
所谓非对称加密算法,即加密和解密使用两个不同的密钥。非对称主要是相对于对称加密算法而言的,对称加密算法有加解密使用同一个秘钥,非对称算法则有一个公钥和一个私钥,公钥与私钥是一对的,这两个共同组成一个解钥,才能实现解密。
Ps:RSA是可以双向加密的:私钥加密,公钥解密;公钥加密,私钥解密。
1.2 主要算法
DH 秘钥交换算法,算是非对称加密算法的起源
RSA 基于因子分解,既能用于数字加密也能用于数字签名
ELGamal 基于离散对数加密
1.3 非对称加密算法的特点
算法强度复杂、安全性依赖于算法与密钥.但是由于算法复杂,使得非对称算法加解密速度没有对称算法加解密的速度快.
对称密钥体制中只有一种密钥,并且是非公开的,如果要解密就得让对方知道密钥.所以保证其安全性就是保证密钥的安全.
非对称密钥体制有两种密钥,其中一个是公开的,这样就可以不需要像对称密码那样向对方传输密钥了.因此安全性就大了很多.
算法复杂度:对称密钥<非对称密钥
加解密速度:对称密钥>非对称密钥
安全性:对称密钥<非对称密钥
1.4 使用到的类和相关参数
KeyPairGenerator:密钥对生成器
KeyPair:密钥对
PublixKey:公钥
PrivateKey :私钥
KeyFactory:作用是生成密钥(包括公钥和私钥)
generatePublic()方法用来生成公钥
generatePrivate()方法用来生成私钥
X509EncodedKeySpec:继承EncodedKeySpec类 ,以编码格式来表示公钥
PKCS8EncodedKeySpec:继承EncodedKeySpec类,以编码格式来表示私钥
DHPublicKey:是PublicKey的某种具体的形式
DHParameterSpec:随从着DH算法来使用的参数的集合
KeyAgreement:该类提供密钥一致性(或者密钥交换)协议的功能
SecretKey:构建的本地秘钥
Cipher:提供加解密的功能
2、DH算法
Diffie-Hellman算法(D-H算法),密钥一致协议。是由公开密钥密码体制的奠基人Diffie和Hellman所提出的一种思想。简单的说就是允许两名用户在公开媒体上交换信息以生成"一致"的、可以共享的密钥。换句话说,就是由甲方产出一对密钥(公钥、私钥),乙方依照甲方公钥产生乙方密钥对(公钥、私钥)。以此为基线,作为数据传输保密基础,同时双方使用同一种对称加密算法构建本地密钥(SecretKey)对数据加密。这样,在互通了本地密钥(SecretKey)算法后,甲乙双方公开自己的公钥,使用对方的公钥和刚才产生的私钥加密数据,同时可以使用对方的公钥和自己的私钥对数据解密。不单单是甲乙双方两方,可以扩展为多方共享数据通讯,这样就完成了网络交互数据的安全通讯!该算法源于中国的同余定理——中国馀数定理。
DH算法的默认密钥长度是1024,密钥长度必须是64的倍数,在512到1024位之间。
DH是一种基于密钥一致协议的加密算法。
密钥一致协议就是允许两名用户在公开媒体上交换信息以生成"一致"的、可以共享的密钥。
由甲方产出一对密钥(公钥、私钥),乙方依照甲方公钥产生乙方密钥对(公钥、私钥),以此为基线作为数据传输保密基础.同时双方使用同一种对称加密算法构建本地密钥(SecretKey)对数据加密。在互通了本地密钥算法后,甲乙双方公开自己的公钥,使用对方的公钥和刚才产生的私钥加密数据,同时可以使用对方的公钥和自己的私钥对数据解密。
2.1 算法流程
1.甲方构建密钥对,将公钥公布给乙方,将私钥保留;双方约定数据加密算法;乙方通过甲方公钥构建密钥对,将公钥公布给甲方,将私钥保留。
2.甲方使用私钥、乙方公钥、约定数据加密算法构建本地密钥,然后通过本地密钥加密数据,发送给乙方加密后的数据;乙方使用私钥、甲方公钥、约定数据加密算法构建本地密钥,然后通过本地密钥对数据解密。
3.乙方使用私钥、甲方公钥、约定数据加密算法构建本地密钥,然后通过本地密钥加密数据,发送给甲方加密后的数据;甲方使用私钥、乙方公钥、约定数据加密算法构建本地密钥,然后通过本地密钥对数据解密。
2.2 具体实现
使用KeyPairGenerator的getInstance()静态方法创建实例,参数是算法名称.指定密钥对生成器生成指定算法的密钥对。
KeyPairGenerator senderKeyPairGenerator =KeyPairGenerator.getInstance("DH");
使用KeyPairGenerator的initialize()方法初始化密钥的长度.
senderKeyPairGenerator.initialize(512);
使用KeyPairGenerator的generateKeyPair()方法创建KeyPair实例.一个KeyPair实例表示一对密钥,即一个密钥对.包括公钥与私钥.
KeyPair senderKeyPair = senderKeyPairGenerator.generateKeyPair();
KeyPair的getPublic()方法返回PublicKey类型(公钥),getPrivate()方法返回PrivateKey类型(私钥)。
DHPublicKey接口、DHPrivateKey接口分别继承PublicKey接口与PrivateKey接口.
公钥是要发送给接收方的,此处同一类内省略该操作
PublicKey senderPublicKey = senderKeyPair.getPublic();//发送方公钥
使用DHPublicKey的getParams()方法返回DHParameterSpec实例.
DHParameterSpec:此类指定随同DH算法使用的参数集合,用于通过一方的公钥生成另一方的密钥对.
DHParameterSpec dhParameterSpec = ((DHPublicKey) senderPublicKey).getParams();//用发送方的公钥产生算法参数
使用KeyPairGenerator的initialize()初始化方法时,参数还可以是DHParameterSpec的实例.用于通过一方公钥生成密钥对.
KeyPairGenerator receiverKeyPairGenerator = KeyPairGenerator.getInstance("DH"); receiverKeyPairGenerator.initialize(dhParameterSpec);//初始化接收方的KeyPairGenerator KeyPair receiverKeyPair = receiverKeyPairGenerator.generateKeyPair();//生成接收方的密钥对
本地密钥构建:KeyAgreement
KeyAgreement类用于生成本地密钥(提供密钥协定或密钥交换协议的功能).使用其getInstance()静态方法创建实例,参数是算法名,指定生成的本地密钥符合某种特定算法.
KeyAgreement keyAgreement = KeyAgreement.getInstance("DH");
KeyAgreement类的init()方法用于给定密钥初始化此密钥协定.doPhase()方法用于用给定密钥执行此密钥协定的下一个阶段.两个方法的参数都是Key类型,即使用公钥、私钥来初始化密钥协定.
keyAgreement.init(receiverKeyPair.getPrivate());//接收方的私钥 keyAgreement.doPhase(senderKeyPair.getPublic(), true);//发送方的公钥
KeyAgreement类的generateSecret()方法创建本地密钥,参数是对称加密算法名称.返回SecretKey类型.
SecretKey receiverDesKey = keyAgreement.generateSecret("DES");
加密解密,同java加密算法入门(二)-对称加密详解 不在详细讲了
Cipher cipher=Cipher.getInstance("DES"): cipher.init(Cipher.ENCRYPT_MODE, senderDesKey); byte[] result = cipher.doFinal(src.getBytes());
2.3 实现代码
package Asymmetric.encryption;import org.apache.commons.codec.binary.Hex; import javax.crypto.Cipher; import javax.crypto.KeyAgreement; import javax.crypto.SecretKey; import javax.crypto.interfaces.DHPublicKey; import javax.crypto.spec.DHParameterSpec; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PublicKey; import java.util.Objects;/*** {@link http://www.cnblogs.com/allanzhang/}* @author 小卖铺的老爷爷* DH 相当于外面的一层封装。进行密钥交换用的。并不是一种明确的加解密算法*/ public class DHTest {public static final String src = "laoyeye dh";public static void main(String[] args) throws Exception {jdkDH();}public static void jdkDH() throws Exception {//发送方初始化自己的密钥对,并且把公钥发送给接收方KeyPairGenerator senderKeyPairGenerator = KeyPairGenerator.getInstance("DH");senderKeyPairGenerator.initialize(512);KeyPair senderKeyPair = senderKeyPairGenerator.generateKeyPair();PublicKey senderPublicKey = senderKeyPair.getPublic();//公钥是要发送给接收方的,此处同一类内省略该操作//接收方用发送方的公钥初始化自己的密钥对DHParameterSpec dhParameterSpec = ((DHPublicKey) senderPublicKey).getParams();//用发送方的公钥产生算法参数KeyPairGenerator receiverKeyPairGenerator = KeyPairGenerator.getInstance("DH");receiverKeyPairGenerator.initialize(dhParameterSpec);//初始化接收方的KeyPairGeneratorKeyPair receiverKeyPair = receiverKeyPairGenerator.generateKeyPair();//生产接收方的密钥对//DES密钥构建KeyAgreement keyAgreement = KeyAgreement.getInstance("DH");//接收方根据自己的私钥和发送方的公钥创建DES密钥keyAgreement.init(receiverKeyPair.getPrivate());//接收方的私钥keyAgreement.doPhase(senderKeyPair.getPublic(), true);//发送方的公钥SecretKey receiverDesKey = keyAgreement.generateSecret("DES");//发送方根据自己的私钥和接收方的公钥创建DES密钥 keyAgreement.init(senderKeyPair.getPrivate());keyAgreement.doPhase(receiverKeyPair.getPublic(), true);SecretKey senderDesKey = keyAgreement.generateSecret("DES");//判断两方得到的DES密钥是不是相等的if (Objects.equals(senderDesKey, receiverDesKey)) {System.out.println("双方密钥相同");}//加密Cipher cipher = Cipher.getInstance("DES");cipher.init(Cipher.ENCRYPT_MODE, senderDesKey);byte[] result = cipher.doFinal(src.getBytes());System.out.println("JDK DH ENCRYPT:" + Hex.encodeHexString(result));//解密 cipher.init(Cipher.DECRYPT_MODE, receiverDesKey);result = cipher.doFinal(result);System.out.println("JDK DH DECRYPT:" + new String(result));}}
View Code
3、RSA算法
这种算法1978年就出现了,它是第一个既能用于数据加密也能用于数字签名的算法。它易于理解和操作,也很流行。算法的名字以发明者的名字命名:Ron Rivest, AdiShamir 和Leonard Adleman。
这种加密算法的特点主要是密钥的变化,java加密算法入门(二)-对称加密详解 一文中我们看到DES只有一个密钥。相当于只有一把钥匙,如果这把钥匙丢了,数据也就不安全了。RSA同时有两把钥匙,公钥与私钥。同时支持数字签名。数字签名的意义在于,对传输过来的数据进行校验。确保数据在传输工程中不被修改。
RSA算法的JDK实现默认密钥长度是1024,BC则是2048,密钥长度必须是64的倍数,在512到65536位之间。
RSA目前还没有被破解,是使用最多的非对称加密算法.
有些算法只规定了公钥加密、私钥解密,RSA算法则支持公钥加密、私钥解密.私钥加密、公钥解密。
3.1 算法流程
1.甲方构建密钥对儿,将公钥公布给乙方,将私钥保留。
2.甲方使用私钥加密数据,然后用私钥对加密后的数据签名,发送给乙方签名以及加密后的数据;乙方使用公钥、签名来验证待解密数据是否有效,如果有效使用公钥对数据解密。
3.乙方使用公钥加密数据,向甲方发送经过加密后的数据;甲方获得加密数据,通过私钥解密。
Ps:关于数字签名会在后续的章节中介绍。可以看看这个帖子了解下http://justjavac.iteye.com/blog/1144151
一般公司这样做的。
甲乙公司各有自己的一套公钥私钥。
甲用乙公布的公钥加密,信息传递到乙,乙用自己的私钥解密。 --- 这一套是乙方的公私钥。
乙用甲公布的公钥加密,信息传递到甲,甲用自己的私钥解密。 --- 这一套是甲方的公私钥。
注:公钥长度远远小于私钥,公钥长度比较短,便于公钥保存。
3.2 代码实现
package Asymmetric.encryption;import org.apache.commons.codec.binary.Hex; import javax.crypto.Cipher; import java.security.KeyPair; import java.security.KeyPairGenerator; /*** {@link http://www.cnblogs.com/allanzhang/}* @author 小卖铺的老爷爷**/ public class RSATest {public static final String src = "laoyeye rsa";public static void main(String[] args) throws Exception {jdkRSA();}public static void jdkRSA() throws Exception {//初始化密钥KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");keyPairGenerator.initialize(512);//512~65532KeyPair keyPair = keyPairGenerator.generateKeyPair();//私钥加密,公钥解密Cipher cipher = Cipher.getInstance("RSA");cipher.init(Cipher.ENCRYPT_MODE, keyPair.getPrivate());byte[] result = cipher.doFinal(src.getBytes());System.out.println("**私钥加密,公钥解密**");System.out.println("加密:" + Hex.encodeHexString(result));cipher.init(Cipher.DECRYPT_MODE, keyPair.getPublic());result = cipher.doFinal(result);System.out.println("解密:" + new String(result));} }
4、ElGamal算法
ElGamal算法,是一种较为常见的加密算法,它是基于1985年提出的公钥密码体制和椭圆曲线加密体系。既能用于数据加密也能用于数字签名,其安全性依赖于计算有限域上离散对数这一难题。在加密过程中,生成的密文长度是明文的两倍,且每次加密后都会在密文中生成一个随机数K,在密码中主要应用离散对数问题的几个性质:求解离散对数(可能)是困难的,而其逆运算指数运算可以应用平方-乘的方法有效地计算。也就是说,在适当的群G中,指数函数是单向函数。
特点:
1、在JDK里并没有提供对ElGamal算法的实现.而是通过BouncyCastle实现.
2、只提供公钥加密,私钥解密,不提供私钥加密,公钥解密
3、ElGamal算法支持数据加密与数字签名.
4、密钥长度:160~16384(8的倍数),默认的密钥长度为1024.
4.1 算法流程
1.乙方构建密钥对儿,将公钥公布给甲方,将私钥保留。
2.甲方使用公钥加密数据,然后用公钥对加密后的数据签名,发送给乙方签名以及加密后的数据;乙方使用私钥、签名来验证待解密数据是否有效,如果有效使用私钥对数据解密。
4.2 具体步骤
在使用之前需要为JDK添加新的Provider.
Security.addProvider(new BouncyCastleProvider());
RSA初始化密钥对是通过KeyPairGenerator实现的.而ElGamal初始化密钥对则是通过AlgorithmParameterGenerator实现的.
使用AlgorithmParameterGenerator的getInstance()静态方法获取AlgorithmParameterGenerator实例,参数是算法名.
AlgorithmParameterGenerator algorithmParameterGenerator = AlgorithmParameterGenerator.getInstance("Elgamal");
使用AlgorithmParameterGenerator的init()方法进行初始化密钥长度.
algorithmParameterGenerator.init(256);
JDK没有提供对ElGamal的支持,但是jce提供了构建秘钥对的方式DHParameterSpec,具体方式见代码
// 生成算法参数 AlgorithmParameters algorithmParameters = algorithmParameterGenerator.generateParameters(); // 构建参数材料 //JDK没有提供对ei的支持,但是jce框架提供了构建秘钥对的方式DHParameterSpec DHParameterSpec dhParameterSpec = (DHParameterSpec)algorithmParameters.getParameterSpec(DHParameterSpec.class); // 实例化密钥对生成器 KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("Elgamal"); // 初始化密钥对生成器 keyPairGenerator.initialize(dhParameterSpec, new SecureRandom()); KeyPair keyPair = keyPairGenerator.generateKeyPair();
到这一步后就和RSA的步骤类似了,可参考上文或者查看实现代码。
4.3 实现代码
package Asymmetric.encryption;import java.security.AlgorithmParameterGenerator; import java.security.AlgorithmParameters; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.Security; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec;import javax.crypto.Cipher; import javax.crypto.spec.DHParameterSpec;import org.apache.commons.codec.binary.Base64; import org.bouncycastle.jce.provider.BouncyCastleProvider; /*** {@link http://www.cnblogs.com/allanzhang/}* @author 小卖铺的老爷爷**/ public class ElGamalTest {public static final String src = "laoyeye Elgamal test";public static void main(String[] args) {jdkElgamal();}// jdk实现:“公钥加密,私钥解密” , 因为Elgamal不支持“私钥加密、公钥解密”。public static void jdkElgamal(){ try {// 加入对BouncyCastle支持 Security.addProvider(new BouncyCastleProvider());// 初始化密钥AlgorithmParameterGenerator algorithmParameterGenerator = AlgorithmParameterGenerator.getInstance("Elgamal");// 初始化参数生成器algorithmParameterGenerator.init(256);// 生成算法参数AlgorithmParameters algorithmParameters = algorithmParameterGenerator.generateParameters();// 构建参数材料//JDK没有提供对ei的支持,但是jce框架提供了构建秘钥对的方式DHParameterSpecDHParameterSpec dhParameterSpec = (DHParameterSpec)algorithmParameters.getParameterSpec(DHParameterSpec.class);// 实例化密钥对生成器KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("Elgamal"); // 初始化密钥对生成器 keyPairGenerator.initialize(dhParameterSpec, new SecureRandom());KeyPair keyPair = keyPairGenerator.generateKeyPair();// 公钥PublicKey elGamalPublicKey = keyPair.getPublic();// 私钥 PrivateKey elGamalPrivateKey = keyPair.getPrivate();System.out.println("Public Key:" + Base64.encodeBase64String(elGamalPublicKey.getEncoded()));System.out.println("Private Key:" + Base64.encodeBase64String(elGamalPrivateKey.getEncoded()));// 初始化公钥 // 密钥材料转换X509EncodedKeySpec x509EncodedKeySpec2 = new X509EncodedKeySpec(elGamalPublicKey.getEncoded());// 实例化密钥工厂KeyFactory keyFactory = KeyFactory.getInstance("Elgamal");// 产生公钥PublicKey publicKey2 = keyFactory.generatePublic(x509EncodedKeySpec2);// 数据加密 // Cipher cipher = Cipher.getInstance("Elgamal");Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE, publicKey2);byte[] result2 = cipher.doFinal(src.getBytes());System.out.println("Elgamal ---- 加密:" + Base64.encodeBase64String(result2));// 数据解密PKCS8EncodedKeySpec pkcs8EncodedKeySpec5 = new PKCS8EncodedKeySpec(elGamalPrivateKey.getEncoded());keyFactory = KeyFactory.getInstance("Elgamal");PrivateKey privateKey5 = keyFactory.generatePrivate(pkcs8EncodedKeySpec5); // Cipher cipher5 = Cipher.getInstance("Elgamal");Cipher cipher5 = Cipher.getInstance(keyFactory.getAlgorithm()); cipher5.init(Cipher.DECRYPT_MODE, privateKey5);byte[] result5 = cipher5.doFinal(result2);System.out.println("Elgamal ---- 解密:" + new String(result5));} catch (Exception e) {e.printStackTrace();}}}
View Code
4.4 遇到的问题
代码报错:“Illegal key size or default parameters”异常,是因为美国的出口限制,Sun通过权限文件(local_policy.jar、US_export_policy.jar)做了相应限制。因此存在一些问题。
Java 6 无政策限制文件:http://www.oracle.com/technetwork/java/javase/downloads/jce-6-download-429243.html
Java 7 无政策限制文件:http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html
找到对应jdk的安装目录。D:\JDK1.6\jdk1.7.0_45\jre\lib\security目录下,对应覆盖local_policy.jar和US_export_policy.jar两个jar包就可以了。
补充:
关于源码中PKCS8EncodedKeySpec,X509EncodedKeySpec密钥的转换,实际上并不需要转换,也不需要重新生成keyfactory。因为具体我也没应用过,可能是实际项目中一般会这样,因为实际接受方和发送方并不知道对方的密钥的encoded format(编码格式),所以需要转换成自己使用encoded format。而KeyFactory就是转换格式后重新生成私钥,公钥。
总结:
1、对称加密算法中使用的是密钥(SecretKey),非对称加密算法中使用的是密钥对(公钥、私钥)。
2、DH算法比较复杂,需要根据公钥生成自己的秘钥对,然后使用公钥和自己的私钥生成自己的本地秘钥在进行加密
3、RSA相对来讲简单的多,支持公钥加密、私钥解密,私钥加密、公钥解密。
4、ElGamal算法和RSA类似,但是只支持公钥加密,私钥解密,不支持私钥加密,公钥解密。
源码地址:https://github.com/allanzhuo/study
转载于:https://www.cnblogs.com/laoyeye/p/7040539.html
java加密算法入门(三)-非对称加密详解相关推荐
- java RSA非对称加密详解
简介 RSA公钥加密算法是1977年由罗纳德·李维斯特(Ron Rivest).阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的.1987年首次公布,当 ...
- 对称加密和非对称加密详解
目录 一.对称加密(Symmetric Cryptography) 二.非对称加密(Asymmetric Cryptography) 三.总结 一.对称加密(Symmetric Cryptograph ...
- 对称加密,非对称加密详解
在使用一些软件或者是系统的时候,我们常常听到或者看到"公钥","私钥"这两个词,比如,我们在使用git的时候,常常要去先使用git生成自己的公钥和私钥,然后将公 ...
- 常用的安全算法-数字摘要、对称加密、非对称加密详解
本文仅介绍摘要算法.对称加密算法.非对称加密算法的使用场景和使用方法. 1.数字摘要 说明:数字摘要是将任意长度的消息变成固定长度的短消息,它类似于一个自变量是消息的函数,也就是Hash函数.数字摘要 ...
- 细说Java性能测试第三课 性能测试详解2
如何制定一份有效的性能测试方案? 上一讲我们学习了性能测试的场景,并且明确了每个场景的核心意义,这一讲我将带你学习如何做好一份性能测试方案,相信你对测试方案这个概念并不陌生,那如何做好一份性能测试方案 ...
- Java集合(四) LinkedList详解
在上篇文章Java集合(三) ArrayList详解的学习和源码分析中,我们知道ArrayList是以数组实现,它的优势是查询性能高,劣势是按顺序增删性能差.如果在不确定元素数量的情况时,不建议使 ...
- eclipse java 逆向工程_Mybatis 逆向工程的三种方法详解
Mybatis 逆向工程 逆向工程通常包括由数据库的表生成 Java 代码 和 通过 Java 代码生成数据库表.而Mybatis 逆向工程是指由数据库表生成 Java 代码. Mybaits 需要程 ...
- RSA加密 — 详解
转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/120316606 本文出自[赵彦军的博客] 文章目录 推荐 RSA 简介 RSA 常 ...
- AES加密 — 详解
转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/120285594 本文出自[赵彦军的博客] 文章目录 推荐 AES 简介 对称加密 ...
最新文章
- freemarker中js里面取字符串,换行导致报错的解决办法
- ubantu18.04使用docker部署mysql5.7及在宿主机登录容器内mysql
- 《LINUX内核设计与实现》第五章学习总结
- python类的构造方法名称_搞懂Python的类和对象名称空间
- modbus软件开发实战指南_C++核心准则?GSL:指南支持库
- java还是c 2017_2017年9月编程语言排行榜:Java、C与C++三巨头还能统治排行榜多久?...
- ASP.NET Core + Angular 2 Template for Visual Studio
- html中加入scrip代码,HTML script 标签 | 菜鸟教程
- jsp java代码取session_jsp中的session在java文件中取到
- 第五次作业 第三章例题
- homestead.yaml配置详解
- Java:结合JavaSocket编程开发文本处理程序
- 零基础入门学习汇编语言~基础知识~机器语言与汇编语言的产生及组成
- 市场热门身份证识别性能测评对比
- windows电脑桌面旋转快捷键
- windows 10专业版关闭自动更新
- Cesium竖直飞线
- 第二节 控制系统的数学模型——传递函数
- 如何查看linux内核版本
- matlab 毕业论文题目,matlab论文题目
热门文章
- MyBatis 多表关联相同字段的解决方案
- 【微型计算机原理与接口技术】80X86微处理器发展与内部结构
- linux 比较内容,Linux命令比较文件内容
- ios 画带有箭头的线_ios纯色箭头与渐变色箭头的实现
- 数据分析方法(一):对比与对标
- daysmatter安卓版_days matter
- tomcat 启动需要java环境吗?_三分钟教你Windows环境下,如何设置Tomcat随机自动启动?...
- 数组模拟乘法(大数乘法)
- GiraffeDet的学习笔记
- 目标检测——夏侯南溪目标检测模型之输出信息显示