精华内容
下载资源
问答
  • 什么是SM2算法

    千次阅读 2018-05-07 11:12:13
    1.SM2算法简介SM2算法与RSA算法一样,同属于非对称算法体系,是属于椭圆曲线加密(ECC)算法的一种。但与RSA算法不同的是RSA算法是基于大整数分解数学难题,SM2算法是基于椭圆曲线上点群离散对数难题。 相对于RSA...

    SM2算法是一种新的国产非对称算法,相对于RSA算法,它更先进。基于国家商业密码安全等原因,国家密码管理部门正式全国范围内大力推广。

    1.SM2算法简介

    SM2算法与RSA算法一样,同属于非对称算法体系,是属于椭圆曲线加密(ECC)算法的一种。但与RSA算法不同的是RSA算法是基于大整数分解数学难题,SM2算法是基于椭圆曲线上点群离散对数难题。
      相对于RSA算法,SM2算法具有以下优点:
      安全性高。192位的SM2密码强度已经比RSA 2048位密码强度要高。
      存储空间小。SM2算法的密码一般使用192-256位,RSA算法密码一般需要使用2048-4096位。
      签名速度快。SM2在私钥运算上,速度远比RSA快得多。
      国产算法。由国家密码管理部门制订规范,不存在不可公开的密码,保证无国外可利用的后门。
      目前认为在国内被非常广泛使用的RSA 1024位算法不再安全,国家密码管理局下达了通知:自2011年7月1日起,投入运行并使用公钥密码的信息系统,应使用SM2椭圆曲线密码算法。

    展开全文
  • DH 加密算法的使用

    万次阅读 2016-08-12 20:56:14
    而现在将要介绍的是 DH 算法属于非对称密码算法,根据对称密码的概念,很容易知道,非对称密码算法就是解密和加密过程中使用不同密钥的算法。对称密码算法什么局限呢?由于加密和解密使用相同的数据,所以我们在...

    DH 算法的介绍

    上面介绍的 DES,3DES,AES 算法都是对称密码算法,所谓对称,在上面也解释了,就是加密和解密的过程中使用相同的密钥 。而现在将要介绍的是 DH 算法,属于非对称密码算法,根据对称密码的概念,很容易知道,非对称密码算法就是解密和加密过程中使用不同密钥的算法。

    对称密码算法有什么局限呢?由于加密和解密使用相同的数据,所以我们在发送密文的同时,需要将密钥发送给对方,这个时候假如我们的数据和密钥同时被黑客截获了呢?那么我们对数据加密也就失去了意义,唯一保证安全的方法就是,保证密钥不被黑客截取到,怎么才能做到呢?写在纸上亲手交给对方,这样最安全了,但是这往往不可能做到,所以才出现了非对称加密算法。

    DH 算法是怎么加密的呢? 过程比较复杂,首先我们假设发送方是 A,接受方是 B。A 首先生成公钥和密钥,将公钥发送出去,B 接收到 A发送的公钥,然后利用该公钥生成自己的公钥和密钥,再将自己的公钥 发送给 A,这个时候 A 拥有了自己的公钥,密钥和 B 的公钥,B 拥有了自己的公钥密钥和 A 的公钥。

    之后, A 就可以使用 A自己的密钥 + B的公钥 获取到本地的密钥,B也是如此,这个时候 A 和 B 生成的本地密钥其实是相同的,这样的话也就变成了用相同的密钥加密,用相同的密钥解密。而且这样的话,我们数据传递过程中传递的是 A 和 B 的公钥,就算被黑客截取了也无济于事,他们不可能凭借着公钥将数据解密,从而保证了数据的安全性。

    DH 算法的使用

    1 . 首先就是发送方初始化密钥对(公钥 + 密钥)

    public static Map<String,Object> initKey() throws Exception{
            // 实例化密钥对生成器
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("DH");
            //初始化密钥对生成器  默认是1024  512-1024 & 64的倍数 
            keyPairGenerator.initialize(1024);
            //生成密钥对
            KeyPair keyPair = keyPairGenerator.generateKeyPair();
    
            DHPublicKey dhPublicKey = (DHPublicKey) keyPair.getPublic();
            DHPrivateKey dhPrivateKey = (DHPrivateKey) keyPair.getPrivate();
    
            Map<String,Object> map = new HashMap<>();
            map.put(PUBLIC_KEY, dhPublicKey);
            map.put(PRIVATE_KEY, dhPrivateKey);
    
            return map;
    
        }
    

    2 . 发送方有了自己的公钥和密钥之后,将自己的公钥发送出去,然后接收方根据收到的公钥,提取其中的参数,计算得出自己的公钥和密钥

    public static Map<String,Object> initKey(byte[] key) throws Exception{
            // 将传进来的公钥数组转化为 PublicKey
            X509EncodedKeySpec encodedKeySpec = new X509EncodedKeySpec(key);
    
            // 实例化密钥工厂
            KeyFactory keyFactory = KeyFactory.getInstance("DH");
    
            // 产生公钥
            DHPublicKey dhPublicKey = (DHPublicKey) keyFactory.generatePublic(encodedKeySpec);
    
            // 剖析获取到的公钥,得到其参数
            DHParameterSpec dhParameterSpec = dhPublicKey.getParams();
    
            // 实例化密钥对生成器
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("DH");
            keyPairGenerator.initialize(dhParameterSpec);
    
            KeyPair keyPair = keyPairGenerator.generateKeyPair();
            DHPublicKey dhPublicKey2 = (DHPublicKey) keyPair.getPublic();
            DHPrivateKey dhPrivateKey = (DHPrivateKey) keyPair.getPrivate();
    
            Map<String,Object> map = new HashMap<>();
            map.put(PUBLIC_KEY, dhPublicKey2);
            map.put(PRIVATE_KEY, dhPrivateKey);
            return map;
        }
    

    3 . 第三步就是根据对方的公钥 + 自己的密钥 计算出本地密钥

    public static byte[] getSecretKey(byte[] publickey,byte[] privateKey) throws Exception{
    
            KeyFactory keyFactory = KeyFactory.getInstance("DH");
            X509EncodedKeySpec encodedKeySpec = new X509EncodedKeySpec(publickey);
            DHPublicKey dhPublicKey = (DHPublicKey) keyFactory.generatePublic(encodedKeySpec);
    
            PKCS8EncodedKeySpec encodedKeySpec2 = new PKCS8EncodedKeySpec(privateKey);
            DHPrivateKey dhPrivateKey = (DHPrivateKey) keyFactory.generatePrivate(encodedKeySpec2);
    
            KeyAgreement keyAgreement = KeyAgreement.getInstance("DH");
            keyAgreement.init(dhPrivateKey);
            keyAgreement.doPhase(dhPublicKey, true);
    
            SecretKey secretKey = keyAgreement.generateSecret("AES");
            return secretKey.getEncoded();
        }
    

    4 . 测试,根据如上算法,我们看看 发送方计算得出的公钥和密钥以及接收方计算出的公钥和密钥,还有双方的本地密钥

    public static void main(String[] args) throws Exception {
    
            byte[] aPublicKey;
            byte[] aPrivateKey;
            byte[] aSecretKey;
    
            byte[] bPublicKey;
            byte[] bPrivateKey;
            byte[] bSecretKey;
    
            Map<String, Object> aMap = DHUtil.initKey();
            aPublicKey = DHUtil.getPublic(aMap);
            System.out.println("A Public Key : " + Helper.fromByteToHex(aPublicKey));
            aPrivateKey = DHUtil.getPrivate(aMap);
            System.out.println("A Private Key : " + Helper.fromByteToHex(aPrivateKey));
    
            Map<String, Object> bMap = DHUtil.initKey(aPublicKey);
            bPublicKey = DHUtil.getPublic(bMap);
            System.out.println("B Public Key : " + Helper.fromByteToHex(bPublicKey));
            bPrivateKey = DHUtil.getPrivate(bMap);
            System.out.println("B Private Key : " + Helper.fromByteToHex(bPrivateKey));
    
            aSecretKey = DHUtil.getSecretKey(bPublicKey, aPrivateKey);
            System.out.println("A SecretKey : " + Helper.fromByteToHex(aSecretKey));
            bSecretKey = DHUtil.getSecretKey(aPublicKey, bPrivateKey);
            System.out.println("B SecretKey : " + Helper.fromByteToHex(bSecretKey));
    
        }
    

    查看结果如下

    这里写图片描述

    根据生成的本地密钥,发送方和接收方就可以实现数据传输了,和对称密码算法中介绍的 DES,3DES,AES 相同。

    也可以看到,DH 算法中公钥和密钥的长度是非常长的,所以这种方式的加密效率就没有对称算法高,这也是一种牺牲效率去换取安全性的做法。

    展开全文
  • 对称加密算法是指加密秘钥和解密秘钥相同的算法,即用什么加密就用什么解密,早期安全算法属于这一类。这类安全算法存在最大问题就是密码不容易传递,如果在传递过程中被监听,那么该算法也就随之失效了。战争...

    一、安全算法概述

    安全算法通常被人们分为对称加密算法和非对称加密算法两类。

    对称加密算法是指加密秘钥和解密秘钥相同的算法,即用什么加密就用什么解密,早期的安全算法均属于这一类。目前常见的对称加密算法有AES、DES等。这类安全算法存在的最大问题就是密码不容易传递,如果在传递过程中被监听,那么该算法也就随之失效了。战争剧中经常出现的密码本就属于该类算法,消息发送方和接收方使用相同的密码本进行加解密,安全起见密码本通常需要定期更换,而传递密码本的过程在电视剧中通常颇费周折。

    非对称加密算法就能很好地解决传递密码的问题。非对称加密算法是指加密秘钥和解密秘钥不同的加密算法,即加密用一个密码,解密时使用另一个密码,而加密密码只能加密不能解密,且加密密码和解密密码一一对应。这就不存在密码被监听的问题了,我们结合以下过程来进行解释(明文——需要传送的原消息,密文——加密后的消息:

    ①A有消息要发送给B;
    ②B收到请求后发给A加密秘钥;
    ③A用加密秘钥对明文进行加密;
    ④A将密文发送给B;
    ⑤B用解密秘钥进行解密,得到明文。

    在该过程中,涉及到消息传输的过程有②和④,假设有人监听了这两个过程,可以得到加密秘钥和密文,但因为密文只能用解密秘钥来解密,监听者拿不到解密秘钥,所以也就不能对密文进行解密。所以整个过程是不怕被监听的,甚至可以完全公开,只要B保存好自己的解密秘钥不被泄露即可。非对称加密算法通常利用数学原理来实现,运算量较大,且通常会有明文长度的限制,有两种方法可以解决明文长度限制的问题,一是对明文进行分段加密传输,二是用对称加密算法对明文进行加密,再利用非对称加密算法加密对称加密算法的秘钥进行传输,这样也能达到非对称加密的效果,且运算速度也比较快。

    以上过程是非对称加密算法用来加密消息的过程,其实它还有另外一个用途,就是用来做数字签名。所谓数字签名其实就是发送方对自己发送的数据做出相应的标识,让接收方能够确定发送方的身份,从而确定数据的有效性。过程如下:

    ①A事先向B公布自己的解密秘钥,B进行存储;
    ②A之后有数据要发送给B,就用自己的加密秘钥进行加密,再发送给B;
    ③B收到密文之后用解密秘钥进行解密,如果能解开,则说明消息确实是由A发送,同时A也无法否认自己发送了该消息,因为加密秘钥和解密秘钥一一对应,只有A拥有自己的加密秘钥,该密文能被B解开则说明一定是A用自己的加密秘钥进行加密并发送给B的。

    通过以上过程,B确认了A的身份,并且A不可否认发送消息的行为,实现了签名的作用。在以上过程中,监听者可以获取到A的解密秘钥和密文,虽然监听者可以由此获得明文,但签名的目的并不在于消息的保密,而在于B是否能够确认A的身份。监听者在整个过程中没有获取到A的加密秘钥,也就不能冒充A向B发送消息。故该流程中的消息传递过程也是可对外公开的,并且只要A的加密秘钥不泄露,A的身份就不会被冒充。

    数字签名在实际应用过程中,通常要进行签名的数据比较长,而我们上文也提到过非对称加密算法会有明文长度的限制,所以可利用摘要算法(SHA256、MD5等,下文会进一步详细介绍)和非对称加密算法相结合的方法来实现数字签名。即先对要签名的一段数据利用摘要算法进行摘要提取,提取后的摘要用加密秘钥进行加密,加密后的密文即为签名,然后将签名连同原数据一起发送给接收方。接收方成功接收后,利用解密秘钥先对签名进行解密,得到原数据的摘要,再计算所收到的数据的摘要,如果两者相同,则可确认发送方的身份,数据有效。

    二、RSA算法

    RSA算法是目前公认最安全的加密算法,被广泛应用于银行系统等各个领域,我们常见的RSA-2048中的2048是指秘钥的长度,目前为止该长度的RSA算法还没有被破解过。有关RSA算法的原理请参考以下两篇文章:

    http://www.ruanyifeng.com/blog/2013/06/rsa_algorithm_part_one.html
    http://www.ruanyifeng.com/blog/2013/07/rsa_algorithm_part_two.html

    有关原理方面的东西不再多说,网上各位大神已经讲得比较清楚。结合上文对非对称加密算法的描述来看,RSA算法在用作加密消息的时候是将公钥作为加密秘钥对外公布,将私钥保存好作为解密秘钥;在用作数字签名时,发送方用私钥将数据进行加密(即签名),将公钥对外公布,接收方接收到数据后用公钥进行解密(即验签)。

    RSA的算法实现较为复杂,涉及到大数运算,自己做过一版算法的代码,当然也有参考网上的代码,完整的代码见下面的链接。用C++ 在Visual Studio 2017写的。

    https://download.csdn.net/download/weixin_42967006/11456772

    三、AES算法

    AES是一种对称加密算法,常用的秘钥长度为128/192/256位。我们前面提到过,因为非对称加密算法的明文长度限制和效率问题,可采用对称加密算法和非对称加密算法相结合的方法来进行信息的加密。比较常见的组合就是AES和RSA相结合的方式。关于AES算法的原理我觉得下面一篇文章讲得比较清晰:

    https://blog.csdn.net/u014230646/article/details/79552792

    这篇文章中也有代码,大家可参考,但我当时没有采用,用了另一套代码做了修改,出处忘记了,也是用C++在VS 2017上写的,亲测好用,可自动识别128/192/256位长度的密码。下载链接:

    https://download.csdn.net/download/weixin_42967006/11456846

    四、MD5算法

    MD5算法即上文提到过的摘要算法的一种。所谓摘要算法,即将一段数据通过一定规律地运算和变换,得到一组固定长度的特征值,通常特征值都要比数据的长度小得多,且不论数据多长,特征值的长度总是固定的。此外摘要算法要尽可能地保证在数据发生变化的时候,特征值随之变化,利用该特性,我们可以检验数据在传输过程中是否出错或被篡改,传输数据时将数据和其特征值同时发送给接收方,接收方收到数据后计算其特征值,与收到的特征值进行比对,如果相同则数据有效,不同则数据出错。但摘要算法并不能保证数据和特征值一一对应,我们简单来想:数据长度不限,故数据有无限组,特征值长度有限,故特征值有有限组,无限组的数据对应有限组的特征值,必定存在多组数据对应同一个特征值。同理可知摘要算法是不可逆的,我们不能通过特征值来推出唯一的原数据。此外我们还可以知道,特征值的长度越长,组数就越多,不同数据对应同一个特征值的概率就越小,安全性也就越高。

    摘要算法中大家较为常见的一种是CRC算法,因为其算法简单且有一定的可靠性,被广泛应用于安全性要求不是很高的通信场景中。如果你对CRC较为熟悉,那么就可以将MD5理解为高级版的CRC算法,不过它们在算法原理上其实是完全不同的。CRC算法目前常用的特征值长度有2字节或4字节,而MD5的特征值长度为16字节,所以根据上文的描述我们可以知道MD5比CRC要安全得多。MD5的算法原理可以参考下面一篇文章,里面也有C++实现的代码,在这里不再多说。

    https://blog.csdn.net/dickdick111/article/details/84928228

    五、OpenSSL库

    openssl是一个功能丰富且自包含的开源安全工具箱。它提供的主要功能有:SSL协议实现(包括SSLv2、SSLv3和TLSv1)、大量软算法(对称/非对称/摘要)、大数运算、非对称算法密钥生成、ASN.1编解码库、证书请求(PKCS10)编解码、数字证书编解码、CRL编解码、OCSP协议、数字证书验证、PKCS7标准实现和PKCS12个人数字证书格式实现等功能。
    openssl采用C语言作为开发语言,这使得它具有优秀的跨平台性能。openssl支持Linux、UNIX、windows、Mac等平台。

    简单来说,OpenSSL是一个开源的算法代码库,我们目前主流的安全算法它都支持,使用者可直接调用算法函数接口,也可根据实际情况自行修改源代码。OpenSSL被人们广泛引用,可以说涉及到信息安全的地方就会见到OpenSSL,随着物联网的快速发展,在汽车等传统行业也开始逐渐运用它。只要掌握了OpenSSL的使用,主流的安全算法就几乎都可以实现,我们上文中的三个算法也不例外。

    有关OpenSSL的详细介绍和源码的分析可见下面的链接,可以说非常详细了,在后文中我们主要介绍一下如何来使用它。

    https://www.cnblogs.com/testlife007/p/6738506.html

    1、OpenSSL库的编译

    ①需要先安装Visual Studio,我这里用的是Visual Studio 2017,没有安装过的同学可从下面的链接下载安装,对于Visual Studio的安装及破解这里不多说,如果没有操作过可百度,网上教程很多。

    链接:https://pan.baidu.com/s/1uO98Qc24X75DuDDlmv7MWg
    提取码:2346

    ②下载并安装ActivePerl,下载地址如下,下载时需要用邮箱注册一个账号。

    https://www.activestate.com/products/activeperl/downloads/

    安装时遇到下面两步像下图中一样选择,然后一直安装完毕即可。
    在这里插入图片描述
    在这里插入图片描述
    ③下载OpenSSL源码,下载链接:

    https://www.openssl.org/source/

    下载后解压到D:\openssl,如图:
    在这里插入图片描述
    ④运行Visual Studio 2017的命令行工具:
    在这里插入图片描述
    ⑤先输入 d: 并回车进入D盘,如图,我因为把VS装在了D盘所以打开命令行工具默认就在D盘,如果你也是那么请忽略该步骤。
    在这里插入图片描述
    ⑥执行命令:cd d:\openssl 进入到openssl的文件夹:
    在这里插入图片描述
    ⑦我们先来编译32位的动态链接库,之后再说64位以及静态链接库如何操作。执行命令:
    perl Configure VC-WIN32 no-asm
    出现第二张图则该步成功。
    在这里插入图片描述
    在这里插入图片描述
    ⑧执行命令:ms\do_ms.bat
    在这里插入图片描述
    ⑨执行命令:nmake -f ms\ntdll.mak
    该步即开始进行编译,需要花一些时间,执行完成后会在openssl目录下的 out32dll 文件夹中生成静态库、动态库和.exe文件。
    在这里插入图片描述
    ⑩执行命令:nmake -f ms\ntdll.mak test
    对编译结果进行测试,出现第二张图则说明编译成功。
    在这里插入图片描述
    在这里插入图片描述
    ⑪执行命令:nmake -f ms\ntdll.mak install
    在这里插入图片描述
    执行完毕后会在当前盘符生成一个ssl文件夹,路径如下图红框所示,里面会有bin、include、lib三个文件夹,其中include是使用库时需要包含的头文件,bin里面有用来测试的.exe程序,lib里就是算法库。至此32位的动态链接库就编译完成了。
    在这里插入图片描述
    在这里插入图片描述
    ⑫测试:双击bin文件夹里的openssl.exe,执行命令:genrsa -out rsa_private_key.pem 2048
    在这里插入图片描述
    在bin文件夹中就会生成一个2048位的RSA算法的私钥,双击可用记事本打开,如图:
    在这里插入图片描述

    2、静态链接库及64位库的编译:

    (1)若要编译64位动态链接库,则只需把上边第⑦步中的命令由
    perl Configure VC-WIN32 no-asm 替换为 perl Configure VC-WIN64A no-asm ,其余步骤均相同。
    (2)若要编译32位静态链接库,则需把上边⑨⑩⑪步骤中 的 ntdll.mak 替换为nt.mak 即可,即该三步的命令分别为:
    ⑨nmake -f ms\nt.mak
    ⑩nmake -f ms\nt.mak test
    ⑪nmake -f ms\nt.mak install

    同理,若要编译64位静态链接库,需同时替换以上两处。我把我编译好的四种链接库也传上来了,需要的朋友可自取。

    https://download.csdn.net/download/weixin_42967006/11462022

    3、OpenSSL库的使用

    下面以32位动态链接库为例,演示一下如何使用OpenSSL库中的算法函数来实现我们上文提到的RSA、AES和MD5算法,对比之下就可以知道使用OpenSSL如此便利。下文是从头开始使用我们刚刚编译好的库的步骤和代码,我也把我自己做好的VIsualStudio工程传了上来,如果不想自己做的同学也可自行下载,链接如下:

    https://download.csdn.net/download/weixin_42967006/11464773

    调用OpenSSL库的步骤:

    ①在Visual Studio上新建一个C++控制台工程,然后在【项目】→【属性】→【VC++目录】中的包含目录中添加上面步骤⑪生成的include文件夹路径,在引用目录和库目录中添加lib文件夹路径,如图所示:
    在这里插入图片描述
    ②在建好的C++工程脚本中添加以下头文件,注意:“applink.c”这个文件在D:\openssl\ms路径下有,可以直接添加绝对路径,或像我这样把该文件复制到项目主脚本所在路径下再添加,如果不添加该文件运行时会报错,当初被这个问题困扰了很久,而且其他教程中通常没有提到这个问题。

    #include "pch.h"
    #include <iostream>
    #include "openssl/ssl.h"
    #include <openssl/aes.h>
    #include <openssl/rsa.h>
    #include <openssl/md5.h> 
    #include "applink.c"
    #pragma comment(lib,"libeay32.lib")
    

    ③算法实现

    /************************RSA算法实现************************/
    //生成公钥和私钥
    int GenerateRSAKey(char * cpPrivateKeyPath, char * cpPublicKeyPath, int iLength)
    {
        RSA *pRsaKey = RSA_generate_key(iLength, RSA_F4, NULL, NULL);
        FILE *fp_prikey = NULL;
        if ((fp_prikey = fopen(cpPrivateKeyPath, "w")) == NULL)
        {
            printf("Open private key file failed!");
        }
        PEM_write_RSAPrivateKey(fp_prikey, pRsaKey, NULL, NULL, 0, NULL, NULL);
        fclose(fp_prikey);
        FILE *fp_pubkey = NULL;
        if ((fp_pubkey = fopen(cpPublicKeyPath, "w")) == NULL)
        {
            printf("Open public key file failed!");
        }
        PEM_write_RSAPublicKey(fp_pubkey, pRsaKey);
        fclose(fp_pubkey);
        return 1;
    }
    //使用私钥加密
    int RSA_PrivateKeyEncrypt(char *cInData,char *cOutData, char * cpPrivateKeyPath)
    {
        static RSA *rsa_prikey = NULL;
        FILE *fp_prikey = NULL;
    
        int rsa_len_prikey = 0;
        if ((fp_prikey = fopen(cpPrivateKeyPath, "r")) == NULL)
        {
            printf("Open private key file failed!");
        }
    
        if ((rsa_prikey = PEM_read_RSAPrivateKey(fp_prikey, NULL, NULL, NULL)) == NULL) {
            printf("Read private key failed!");
        }
    
        rsa_len_prikey = RSA_size(rsa_prikey);
        //cOutData = (char*)malloc(rsa_len_prikey);
        if (RSA_private_encrypt(rsa_len_prikey, (unsigned char *)cInData, (unsigned char*)cOutData, rsa_prikey, RSA_NO_PADDING))
            return 1;//success
        else  return 0;//failed
    
    
        RSA_free(rsa_prikey);
        fclose(fp_prikey);
    
    }
    //使用公钥加密
    int RSA_PublicKeyEncrypt(char *cInData, char *cOutData, char * cpPublicKeyPath)
    {
        static RSA *rsa_pubkey = NULL;
        FILE *fp_pubkey = NULL;
    
        int rsa_len_pubkey = 0;
        if ((fp_pubkey = fopen(cpPublicKeyPath, "r")) == NULL)
        {
            printf("Open public key file failed!");
        }
    
        if ((rsa_pubkey = PEM_read_RSAPublicKey(fp_pubkey, NULL, NULL, NULL)) == NULL) {
            printf("Read Public key failed!");
        }
    
        rsa_len_pubkey = RSA_size(rsa_pubkey);
        //cOutData = (char*)malloc(rsa_len_pubkey);
        if (RSA_public_encrypt(rsa_len_pubkey, (unsigned char *)cInData, (unsigned char*)cOutData, rsa_pubkey, RSA_NO_PADDING))
            return 1;//success
        else  return 0;//failed
    
    
        RSA_free(rsa_pubkey);
        fclose(fp_pubkey);
    }
    //使用私钥解密
    int RSA_PrivateKeyDecrypt(char *cInData, char *cOutData, char * cpPrivateKeyPath)
    {
        static RSA *rsa_prikey = NULL;
        FILE *fp_prikey = NULL;
    
        int rsa_len_prikey = 0;
        if ((fp_prikey = fopen(cpPrivateKeyPath, "r")) == NULL)
        {
            printf("Open private key file failed!");
        }
    
        if ((rsa_prikey = PEM_read_RSAPrivateKey(fp_prikey, NULL, NULL, NULL)) == NULL) {
            printf("Read private key failed!");
        }
    
        rsa_len_prikey = RSA_size(rsa_prikey);
        //cOutData = (char*)malloc(rsa_len_prikey);
        if (RSA_private_decrypt(rsa_len_prikey, (unsigned char *)cInData, (unsigned char*)cOutData, rsa_prikey, RSA_NO_PADDING))
            return 1;//success
        else  return 0;//failed
    
    
        RSA_free(rsa_prikey);
        fclose(fp_prikey);
    }
    //使用公钥解密
    int RSA_PublicKeyDecrypt(char *cInData, char *cOutData, char * cpPublicKeyPath)
    {
        static RSA *rsa_pubkey = NULL;
        FILE *fp_pubkey = NULL;
    
        int rsa_len_pubkey = 0;
    
        if ((fp_pubkey = fopen(cpPublicKeyPath, "r")) == NULL)
        {
            printf("Open public key file failed!");
        }
    
        if ((rsa_pubkey = PEM_read_RSAPublicKey(fp_pubkey, NULL, NULL, NULL)) == NULL) {
            printf("Read Public key failed!");
        }
    
        rsa_len_pubkey = RSA_size(rsa_pubkey);
        //cOutData = (char*)malloc(rsa_len_pubkey);
        if (RSA_public_decrypt(rsa_len_pubkey, (unsigned char *)cInData, (unsigned char*)cOutData, rsa_pubkey, RSA_NO_PADDING))
            return 1;//success
        else  return 0;//failed
    
    
        RSA_free(rsa_pubkey);
        fclose(fp_pubkey);
    }
    void DisplayBigNumber(const char cName[],char cInData[], int iLength)
    {
        int i = 0;
        printf("\n%s:", cName);
        if (iLength == 0x00)
        {
            for (i = 0; cInData[i] != 0x00; i++);
            iLength = i;
        }
        for (i = 0; i < iLength; i++)
        {
            if (i % 16 == 0) printf("\n");
            if (i % 4 == 0) printf("\t");
            printf("0x%02X ", (unsigned char)cInData[i]);
        }
        printf("\n\n");
    }
    /*******************************main 测试函数*********************************/
    int main()
    {
        char cInData[] = "0123456789ABCDE";
        DisplayBigNumber("In data", cInData, 16);
    
        /******************RSA-2048-test********************/
        
        char EncryptedData[256] = { 0 };
        char DecryptedData[16] = { 0 };
        char cPrivateKeyPath[] = "rsa_private_key.pem";
        char cPublicKeyPath[] = "rsa_public_key.pem";
       
        //首次运行需先打开下面的函数生成秘钥,后续不需要每次运行都重新生成
        //GenerateRSAKey(cPrivateKeyPath, cPublicKeyPath, 2048);
    
        printf("result=%X\n",RSA_PrivateKeyEncrypt(cInData, EncryptedData, cPrivateKeyPath));
        DisplayBigNumber("RSA private key encrypt result", EncryptedData, 256);
        RSA_PublicKeyDecrypt(EncryptedData, DecryptedData, cPublicKeyPath);
        DisplayBigNumber("RSA public key decrypt result", DecryptedData, 0);
    
        printf("result=%X\n", RSA_PublicKeyEncrypt(cInData, EncryptedData, cPublicKeyPath));
        DisplayBigNumber("RSA public key encrypt result", EncryptedData, 256);
        RSA_PrivateKeyDecrypt(EncryptedData, DecryptedData, cPrivateKeyPath);
        DisplayBigNumber("RSA private key decrypt result", DecryptedData, 16);
    
        /******************AES-128-test********************/
    
        unsigned char aes_key[16];
        char AESEncryptedData[16] = { 0 };
        char AESDecryptedData[16] = { 0 };
        AES_KEY aeskey;
        AES_set_encrypt_key(aes_key, 128, &aeskey);
        AES_encrypt((unsigned char*)cInData, (unsigned char*)AESEncryptedData, &aeskey);
        DisplayBigNumber("AES encrypt result", AESEncryptedData, 16);
        AES_set_decrypt_key(aes_key, 128, &aeskey);
        AES_decrypt((unsigned char*)AESEncryptedData, (unsigned char*)AESDecryptedData, &aeskey);
        DisplayBigNumber("AES encrypt result", AESDecryptedData, 16);
    
        /******************MD5-test********************/
    
        char MD5EncryptedData[17] = { 0 };
    #if 0 //方法1
        MD5((unsigned char*)cInData, strlen(cInData), (unsigned char*)MD5EncryptedData);
    
    #else //方法2
        MD5_CTX temp;  
        MD5_Init(&temp);
        MD5_Update(&temp, cInData, strlen(cInData));
        MD5_Final((unsigned char*)MD5EncryptedData, &temp);
    #endif
        DisplayBigNumber("MD5 encrypt result", MD5EncryptedData, 0);
    
    }
    

    以上就是我对于这几个常用安全算法和OpenSSL库的理解,文中链接了多位大神的文章,也参考了一些别人的代码,在此表示感谢!我在学习这些内容的时候走了很多弯路,尤其是使用OpenSSL库的时候遇到了很多困难,踩过了很多坑,在此做一个整理和总结,以便日后使用,也希望对大家有所帮助,欢迎大家交流指正!

    展开全文
  • Java面试之加密算法

    千次阅读 2019-01-29 16:38:31
    1、Java中常用加密算法 散列算法 ...Base64网络上最常见用于传输8Bit字节码编码方式之一,Base64就是一种基于64个可打印字符来表示二进制数据方法,不属于加密算法,只是编码方式。 ...

    1、Java中常用的加密算法

    散列算法

    • MD5
    • SHA

    对称加密

    • DES
    • 3DES
    • AES

    非对称加密

    • RSA
    • ECC

     

    2、什么是base64

    Base64是网络上最常见的用于传输8Bit字节码的编码方式之一,Base64就是一种基于64个可打印字符来表示二进制数据的方法,不属于加密算法,只是是编码方式。

     

     

    展开全文
  • 在笔试或面试中,经常会问到对称加密算法和非对称加密算法区别,哪些方式属于对称加密,哪些属于非对称加密,哪些地方用到了加密。 下面罗列出几种使用加密解密场景~ 系统中前后端交互敏感字符加密,例如身份证...
  • 当时我愣了一下,因为我把非对称加密与单项散列加密概念弄混淆了,所以更不用说什么非对称加密算法中有什么经典算法,结果当然也让面试官愣了一下,所以今天就花点时间说说PHP中信息加密技术 信息加密技术...
  • android RSA加密使用

    千次阅读 2016-04-22 12:05:02
    RSA属于非对称的算法,具体对称和非对称区别自行百度,在这里不在多余赘述。公钥加密私钥解密或者私钥加密公钥解密,下面说说我们项目里面加密和解密怎么用:我们用法相对来说比较简单,服务器生成公钥和...
  • 谈PHP中信息加密技术

    2017-11-15 11:10:08
    当时我愣了一下,因为我把非对称加密与单项散列加密概念弄混淆了,所以更不用说什么非对称加密算法中有什么经典算法,结果当然也让面试官愣了一下,所以今天就花点时间说说PHP中信息加密技术 信息加密技术...
  • JS加密Java解密报rsa bad argument

    千次阅读 2016-06-23 17:47:41
    一、RSA个ShenMeGui: ...其实一开始叫我用RSA加密我...RSA目前最有影响力公钥加密算法属于非对称加密,也就是用一个大家都知道公钥来加密出来密文,只有拥有私钥人才能解开,目前听说1024比较安
  • 下列算法当中,属于非对称算法的是【D】。 A.RC4 B.GHOST C.DES D.DH 下列选项中不属于加密算法的是【D】。 A.MD5 B.IDEA C.AES D. RC4 下列选项中属于加密算法的是【A】。 A.MD5 B.SHA C.MD4 D. RC4 ...
  • 20200828——https详解

    2020-08-28 01:10:00
    https到底是什么,总说tsl和ssl到底是什么。 https本质 https本质,其实就是http披上了ssl和tls外套,http属于应用层协议,而ssl(安全套接字)和tls(运输层安全)都属于传输层协议。 加密基本概念 明文 ...
  • 2.1.7 冒泡排序算法的时间复杂度是什么? 2.1.8 写出float x 与“零值”比较的if语句 2.1.9 Internet采用哪种网络协议?该协议的主要层次结构? 2.2.0 Internet物理地址和IP地址转换采用什么协议? 2.2.1 IP地址...
  • Java非对称加密源码实例 1个目标文件 摘要:Java源码,算法相关,非对称加密 Java非对称加密源程序代码实例,本例中使用RSA加密技术,定义加密算法可用 DES,DESede,Blowfish等。 设定字符串为“张三,你好,我李四”...
  • JAVA上百实例源码以及开源项目

    千次下载 热门讨论 2016-01-03 17:37:40
     Java非对称加密源程序代码实例,本例中使用RSA加密技术,定义加密算法可用 DES,DESede,Blowfish等。  设定字符串为“张三,你好,我李四”  产生张三密钥对(keyPairZhang)  张三生成公钥(publicKeyZhang...
  • 《数据结构 1800题》

    热门讨论 2012-12-27 16:52:03
    17.以下属于逻辑结构的是(C )。【西安电子科技大学应用 2001一、1】 A.顺序表 B. 哈希表 C.有序表 D. 单链表 二、判断题 1. 数据元素是数据的最小单位。( ) 【北京邮电大学 1998 一、1(2分)】【青岛大学 ...
  • asp.net知识库

    2015-06-18 08:45:45
    #实现18位身份证格式验证算法 身份证15To18 的算法(C#) 一组 正则表达式 静态构造函数 忽略大小写Replace效率瓶颈IndexOf 随机排列算法 理解C#中委托[翻译] 利用委托机制处理.NET中异常 与正则表达式相关几...
  • 特别要提到的是,对于想通过阅读 Andrew S. Tanenbaum和 Albert S. Woodhull的《操作系统:设计与实现》来学习操作系统的读者,本书尤其适合作为你的引路书籍,因为它翔实地介绍了初学者入门时所必需的知识积累,而...
  • 特别要提到的是,对于想通过阅读 Andrew S. Tanenbaum和 Albert S. Woodhull的《操作系统:设计与实现》来学习操作系统的读者,本书尤其适合作为你的引路书籍,因为它翔实地介绍了初学者入门时所必需的知识积累,而...
  • 什么不用线性回归代价函数表示,因为线性回归代价函数可能是非凸,对于分类问题,使用梯度下降很难得到最小值,上面代价函数凸函数 图像如下,即y=1时: 可以看出,当趋于1,y=1,与预测值一致,...
  • 继承和多态 - 什么是继承 / 继承语法 / 调用父类方法 / 方法重写 / 类型判定 / 多重继承 / 菱形继承(钻石继承)和C3算法 综合案例 - 工资结算系统 / 图书自动折扣系统 / 自定义分数类 Day10 - 图形用户界面和游戏...

空空如也

空空如也

1 2
收藏数 32
精华内容 12
关键字:

属于非对称算法的是什么