sha1算法数字签名c语言,RSA/SHA1加密和数字签名算法在开放平台中的应用

加密算法

加密算法分为两大类:1.对称加密算法;2.非对称加密算法。javascript

密钥个数

加密

解密

对称加密

一个

使用密钥加密

使用同一个密钥解密

非对称加密

两个,公钥和私钥

使用其中一把密钥加密

使用另一把密钥解密

RSA非对称加密算法

RSA是目前应用最普遍的非对称加密算法,各类语言都支持RSA算法,如Java,Python,C++(openssl),Go(openssl),PHP(openssl),Object-C,Android,javascript等。

对于一个私钥匙、有且只有一个与之对应的公钥。公/私钥的主流可选位长度为102四、204八、307二、4096....,越长安全系数越高。私钥加密的内容,使用公钥可以解密,一样使用公钥加密的内容,使用私钥也能解密。

在linux系统下,有两种经常使用的工具用于生成RSA密钥对,ssh-keygen和openssl genrsa。

RSA是一个可以同时用于加密和数字签名的算法,典型的应用场景:隐藏原文、防止原文被篡改、身份认证。隐藏原文是全部加密算法的通用功能(要否则怎么叫加密),防止原文被篡改是数字签名的功能,数据传输的具体流程以下:java

甲方构建密钥对,将公钥交给乙方

甲方使用私钥加密原文,而后将加密数据发送给乙方。乙方使用公钥对签名进行解密,获取原文,若是解密失败,则原文被篡改。

乙方给甲方发送原文的时候,先使用公钥对原文加密,将加密数据发送给甲方。甲方使用私钥对签名解密,获取原文,若是解密失败,则原文被篡改。

若是第三方不知道密钥对,则第三方什么都作不了。若是第三方知道公钥,则第三方对甲方的原文具备与乙方同样的阅读权限,但没法篡改甲方的原文,由于没有私钥,没法生成合法的数字签名。

RSA对一次加密的明文的长度是有要求的,在不一样的padding模式下,能加密的明文长度也不相同。以RSA 1024为例,输入的明文的字节数不能超过钥模长1024bits,即最长为128bytes。RSA 1024的不一样padding模式下的明文长度的最大值计算公式:linux

RSA_PKCS1_PADDING RSA_size(1024) - 11 = 117bytes

RSA_PKCS1_OAEP_PADDING RSA_size(1024) - 41 = 87bytes

RSA_NO_PADDING RSA_size(1024) = 128bytes

因为RSA等非对称加密算法对原文长度有限制,且算法效率没有对称加密高,在实际应用中一般被用于传递对称加密算法的密钥(一般是一个随机值),而后通讯双方使用对称加密算法保证数据安全。

数字签名

数字签名是一份数据通过特定的算法计算后得出的特殊标识,用来防止数据在传输过程当中被伪造或篡改,是非对称加密技术与数字摘要技术的综合应用。算法

数字摘要

数字摘要指能够将任意长度的数据,经过一个摘要算法计算获得的固定长度的数据。也就是说摘要算法能够将很长的数据变为一个固定长度的数据,一般计算得出的数据要比原始数据短得多,因此被称为‘摘要’,典型的摘要算法有MD5和SHA1。

数字摘要算法具备如下重要特性:后端

原数据不一样,计算获得的摘要必定不一样,反之,原数据不变,计算获得的摘要必定相同。

没法经过摘要逆运算得到原数据,即摘要计算不可逆。

任意长度的输入数据,通过计算都会得出固定长度的摘要。

加密算法和摘要算法的区别

加密后的密文可使用对应的密钥进行解密,获取原文;摘要是不能进行逆向解密的

加密以后的密文的长度不定;摘要的长度是肯定的

非对称加密对明文的长度有限制;摘要对明文长度无限制

应用场景

非对称加密技术可以确保只有持有密钥对的双方才能获取到正确的数据,但对加密原文的长度有限制,而数字摘要算法可以将输入数据转换为固定长度的摘要,并保证在原数据不变的状况下,摘要计算结果是一致的。这两项技术的特性的结合,就造成了数字签名的经典应用场景:安全

发送者使用MD5(或SHA1)算法提起原文摘要,而后使用私钥对摘要进行加密,把密文与原文一块儿传送给接收者。

接收者使用公钥对密文进行解密,得到摘要,而后使用与发送者同样的摘要算法MD5(或SHA1)对原文提取摘要,比较两个摘要是否相等

摘要相等,说明原文完整且没有被篡改;不相等,说明原文不正确。

数字签名有两种做用:1. 在私钥没有泄漏的状况下,可以确保数据是由发送方签名发送的。 2.可以确保数据是完整的且没有被篡改。可是数据自己是否加密,并非数字签名的做用范畴,由于加密的是摘要,并非数据自己。

RSA和数字签名在Https协议通讯中有经典的应用,这里再也不赘述。ruby

RSA和数字签名在开放平台中的应用

在开放平台中,RSA和数字签名多用于开发者接入的身份验证。app

RSA的应用

独立开发者接入平台时,使用RSA算法做为开发者身份验证的核心算法,如云信通IM平台即便用此种模式。开发者接入平台时,须要以下几个步骤:ssh

建立一个应用app,平台会分配一个SDKAPPID

将SDKAPPID关联到一对RSA的公钥和私钥上,公钥和私钥由平台生成

由云信通IM平台持有公钥,开发者持有私钥

开发者的服务每次调用平台接口时,须要携带使用指定参数和私钥生成的签名,生成签名的公式为:RSA(私钥,SDKAPPID,用户id)

云平台会验证每次接口调用中传入的签名和用户id,首先使用公钥对签名解密,而后验证SDKAPPID是否合法,比对用户id,保证用户id不会被篡改。

每一个签名具备默认的有效期,也就是说,在私钥不变的状况下,一个用户的签名在有效期内是能够反复使用的

在独立开发者接入平台的场景中,开发者本身须要保证私钥的安全,且用户登录的验证由开发者的后端服务来执行,平台并不负责验证用户是否登录,平台仅须要验证服务的调用方是不是合法的开发者。经典的交互流程以下所示:

43f715de33ce65ad0f17a6fc0a8c3aa6.png

数字签名的应用

SHA1哈希算法生成数字签名也被应用于独立开发者接入模式,如融云开放平台、网易云信就使用此模式。开发者接入平台时,须要以下几个步骤:工具

开发者申请接入平台,由平台分配AppKey和Secret,Secret由开发者确保安全

在全部平台服务端 API 接口的请求中,都须要附带如下4个HTTP Request Header: | 名称| 类型 | 说明 |

| AppKey | String | 平台分配的 App Key |

| Nonce| String | 随机数,长度无限制 | | Timestamp | String | 时间戳 | | Signature | String | 数字签名 |

数字签名是用于检验开发者是否合法的关键,其生成方式为:App Secret、Nonce (随机数)、Timestamp (时间戳)三个字符串按前后顺序拼接成一个字符串并进行 SHA1 哈希计算。

这种开发者接入模式中,数字签名起到几个做用:

用于验证开发者的合法性

用于保证关键参数如AppKey,Timestamp不被篡改(前提是开发者保证了Secret的安全)

SHA1没有明文长度的限制,这也是其比RSA算法有优点的地方,但SHA1算法是摘要算法,其计算出来的结果是没法解密的。

RSA算法数字签名C语言编程实现示例: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <openssl/rsa.h> #include <openssl/pem.h> #include <openssl/err.h> #define KEY_LENGTH 2048 #define BLOCK_SIZE KEY_LENGTH/8-11 int main(){ RSA *keypair; unsigned char plain_text[100] = "Hello, RSA!"; unsigned char cipher_text[KEY_LENGTH/8]; unsigned char decrypted_text[KEY_LENGTH/8]; unsigned char signature[KEY_LENGTH/8]; unsigned int signature_len; int decrypted_len; // 生成 RSA 密钥对 keypair = RSA_generate_key(KEY_LENGTH, RSA_F4, NULL, NULL); // 使用私钥签名 if (RSA_sign(NID_sha256, plain_text, strlen(plain_text), signature, &signature_len, keypair) != 1) { fprintf(stderr, "RSA sign error!\n"); RSA_free(keypair); return -1; } // 使用公钥验签 if (RSA_verify(NID_sha256, plain_text, strlen(plain_text), signature, signature_len, keypair) != 1) { fprintf(stderr, "RSA verify error!\n"); RSA_free(keypair); return -1; } // 使用公钥加密 int cipher_len = RSA_public_encrypt(strlen(plain_text), plain_text, cipher_text, keypair, RSA_PKCS1_PADDING); if (cipher_len == -1) { fprintf(stderr, "RSA public encrypt error!\n"); RSA_free(keypair); return -1; } printf("Cipher text: "); for (int i = 0; i < cipher_len; i++) { printf("%02x", cipher_text[i]); } printf("\n"); // 使用私钥解密 decrypted_len = RSA_private_decrypt(cipher_len, cipher_text, decrypted_text, keypair, RSA_PKCS1_PADDING); if (decrypted_len == -1) { fprintf(stderr, "RSA private decrypt error!\n"); RSA_free(keypair); return -1; } decrypted_text[decrypted_len] = '\0'; printf("Decrypted text: %s\n", decrypted_text); RSA_free(keypair); return 0; } ``` 需要注意的是,这里用到了 OpenSSL 库,需要在编译时链接该库,同时需要在代码包含相关的头文件。此外,为了方便,这里的签名、验签、加密、解密都是在同一个程序实现,实际应用可能需要拆分成不同的模块。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值