linux rsa加密算法,.net core linux下的RSA解密

但是由于这里的RSA加密/解密主要是针对于由OpenSSL生成的公钥/私钥字符串。ssh-keygen -t rsa 命令生成的公钥私钥是不行的。

如果使用带签名的加密方式字符串就会出现

rsa.ImportParameters(rsaParameters);

无法解析到相应byte的问题

如果使用

rsa = new RSACryptoServiceProvider(keySize, rsaParams);

可以解析带签名的RSA加密字符串,但是在linux下会出现错误

解析出错:System.PlatformNotSupportedException: 'CspParameters' requires Windows Cryptographic API (CAPI), which is not available on this platform.

有依赖包依赖于windows环境下的dll,linux下无法解析。

解决方案:

将参考部分的RSAHelper中rsa.ImportParameters(rsaParameters);获取公钥私钥byte的解析方案用下面解析方式替换掉

///

/// 用PEM格式密钥对创建RSA,支持PKCS#1、PKCS#8格式的PEM

///

public static System.Security.Cryptography.RSA FromPEM(string pem)

{

var rsa = System.Security.Cryptography.RSA.Create();

var param = new RSAParameters();

var base64 = _PEMCode.Replace(pem, "");

var data = RSA_Unit.Base64DecodeBytes(base64);

if (data == null)

{

throw new Exception("PEM内容无效");

}

var idx = 0;

//读取长度

Func readLen = (first) => {

if (data[idx] == first)

{

idx++;

if (data[idx] == 0x81)

{

idx++;

return data[idx++];

}

else if (data[idx] == 0x82)

{

idx++;

return (((int)data[idx++]) << 8) + data[idx++];

}

else if (data[idx] < 0x80)

{

return data[idx++];

}

}

throw new Exception("PEM未能提取到数据");

};

//读取块数据

Func readBlock = () => {

var len = readLen(0x02);

if (data[idx] == 0x00)

{

idx++;

len--;

}

var val = data.sub(idx, len);

idx += len;

return val;

};

//比较data从idx位置开始是否是byts内容

Func eq = (byts) => {

for (var i = 0; i < byts.Length; i++, idx++)

{

if (idx >= data.Length)

{

return false;

}

if (byts[i] != data[idx])

{

return false;

}

}

return true;

};

if (pem.Contains("PUBLIC KEY"))

{

/****使用公钥****/

//读取数据总长度

readLen(0x30);

if (!eq(_SeqOID))

{

throw new Exception("PEM未知格式");

}

//读取1长度

readLen(0x03);

idx++;//跳过0x00

//读取2长度

readLen(0x30);

//Modulus

param.Modulus = readBlock();

//Exponent

param.Exponent = readBlock();

}

else if (pem.Contains("PRIVATE KEY"))

{

/****使用私钥****/

//读取数据总长度

readLen(0x30);

//读取版本号

if (!eq(_Ver))

{

throw new Exception("PEM未知版本");

}

//检测PKCS8

var idx2 = idx;

if (eq(_SeqOID))

{

//读取1长度

readLen(0x04);

//读取2长度

readLen(0x30);

//读取版本号

if (!eq(_Ver))

{

throw new Exception("PEM版本无效");

}

}

else

{

idx = idx2;

}

//读取数据

param.Modulus = readBlock();

param.Exponent = readBlock();

param.D = readBlock();

param.P = readBlock();

param.Q = readBlock();

param.DP = readBlock();

param.DQ = readBlock();

param.InverseQ = readBlock();

}

else

{

throw new Exception("pem需要BEGIN END标头");

}

rsa.ImportParameters(param);

return rsa;

}

依赖方法

///

/// 封装的一些通用方法

///

public class RSA_Unit

{

static public string Base64EncodeBytes(byte[] byts)

{

return Convert.ToBase64String(byts);

}

static public byte[] Base64DecodeBytes(string str)

{

try

{

return Convert.FromBase64String(str);

}

catch

{

return null;

}

}

///

/// 把字符串按每行多少个字断行

///

static public string TextBreak(string text, int line)

{

var idx = 0;

var len = text.Length;

var str = new StringBuilder();

while (idx < len)

{

if (idx > 0)

{

str.Append('\n');

}

if (idx + line >= len)

{

str.Append(text.Substring(idx));

}

else

{

str.Append(text.Substring(idx, line));

}

idx += line;

}

return str.ToString();

}

}

static public class Extensions

{

///

/// 从数组start开始到指定长度复制一份

///

static public T[] sub(this T[] arr, int start, int count)

{

T[] val = new T[count];

for (var i = 0; i < count; i++)

{

val[i] = arr[start + i];

}

return val;

}

static public void writeAll(this Stream stream, byte[] byts)

{

stream.Write(byts, 0, byts.Length);

}

}

这样经过测试上线可以在linux下解析出带签名的RSA加密字符串

var rsa = new RSAHelper(RSAType.RSA, Encoding.UTF8, rsaprivate);

Console.WriteLine("原始字符串:" + connection);

//加密

// string enStr = rsa.Encrypt(str);

// Console.WriteLine("加密字符串:" + enStr);

//解密

// string deStr = rsa.DecodeOrNull(connection);

var deStr = rsa.Decrypt(connection);

Console.WriteLine("解密字符串:" + deStr);

string finalconnection = MySqlHelper(deStr);

被坑了一下午,在同事的帮助下解决这个问题,希望能帮助到那些还再坑里的同学吧O(∩_∩)O哈哈~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: RSA是一种非对称加密算法,使用公钥加密和私钥解密。在Linux和Qt环境下,我们可以使用OpenSSL库对RSA进行加密和解密操作。 在Qt中使用OpenSSL库,需要在.pro文件中加入如下语句: LIBS += -lssl -lcrypto 这样就可以链接OpenSSL库。 RSA算法分为公钥加密和私钥解密两个步骤。在Qt中,我们可以使用该库中的RSA_generate_key函数生成一对公私钥,该函数需要传入一个整型值作为密钥位数。 生成密钥对后,我们可以使用RSA_public_encrypt函数和RSA_private_decrypt函数分别对明文进行加密和密文进行解密操作。 下面是一个简化版的RSA加密算法实现: #include <openssl/rsa.h> #include <openssl/pem.h> #include <stdio.h> #include <stdlib.h> #include <string.h> int main() { // 生成密钥对 RSA *r = RSA_generate_key(1024, RSA_F4, NULL, NULL); // 明文和密文 unsigned char plaintext[100] = "Hello, world!"; unsigned char ciphertext[1024] = {0}; unsigned char output[100] = {0}; // 加密 int len = RSA_public_encrypt(strlen((const char *)plaintext), plaintext, ciphertext, r, RSA_PKCS1_PADDING); printf("Ciphertext: %s\n", ciphertext); // 解密 len = RSA_private_decrypt(len, ciphertext, output, r, RSA_PKCS1_PADDING); printf("Plaintext: %s\n", output); return 0; } 这是一个简单的RSA加密解密程序,其中使用了OpenSSL库中的RSA_generate_key、RSA_public_encrypt和RSA_private_decrypt函数分别生成密钥对、加密明文和解密密文。 ### 回答2: RSA加密算法是一种非对称加密算法,常用于信息安全领域。使用Qt实现RSA加密解密,需要先了解RSA算法及其原理。 首先,RSA算法中需要生成一对公私钥,公钥用于加密,私钥用于解密。生成公私钥的过程如下: 1. 随机选择两个不同的质数p和q 2. 计算n=p*q 3. 计算欧拉函数φ(n)=(p-1)*(q-1) 4. 选择一个整数e(1<e<φ(n)),e与φ(n)互质 5. 计算d,满足d*e ≡ 1 (mod φ(n)) 6. 公钥为(n,e),私钥为(n,d) 加密过程如下: 1. 将待加密数据转换为整数m(0<=m<n) 2. 计算密文c=m^e (mod n) 解密过程如下: 1. 接收到密文c 2. 计算明文m=c^d (mod n) 使用Qt实现RSA加密解密,可以参考以下步骤: 1. 生成公私钥对:随机选择两个质数p和q,计算n、φ(n)、e和d,得到公钥(n,e)和私钥(n,d)。 2. 加密:将待加密数据转换为整数m,计算密文c=m^e(mod n)。 3. 解密:接收到密文c,计算明文m=c^d(mod n)。 4. 实现一个简化版的RSA加密算法:通过Qt提供的大数类,实现上述步骤。 5. 测试:输入待加密的字符串,将其转换为整数后加密,再将密文解密并转回字符串,与原字符串进行比较,验证加解密是否正确。 总的来说,使用Qt实现RSA加密解密需要了解RSA算法原理,并掌握Qt提供的大数类。在实现过程中,需要注意数据类型的转换和边界处理,保证算法的正确性和运行效率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值