C# RSA加密

项目需要对接Java的接口,一些参数需要用到Rsa加密,经过多次尝试,该工具类可以跟Java的接口正确解析,在此记录一下,后面会附上Java的代码。

C# RSA工具类代码:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using static System.Runtime.InteropServices.JavaScript.JSType;

namespace Tools
{
    public class RSAHelper
    {
        public static string PubEncrypt1(string pubKey, string src)
        {
            try
            {
                using (RSA rsa = RSA.Create())
                {
                    // 导入公钥(PEM 格式或 XML 格式)
                    //ImportPublicKey(rsa, pubKey);
                    var pub = pubKey.Replace("-----BEGIN PUBLIC KEY-----", "").Replace("-----END PUBLIC KEY-----", "");
                    rsa.ImportSubjectPublicKeyInfo(Convert.FromBase64String(pub), out _); 

                    byte[] dataToEncrypt = Encoding.UTF8.GetBytes(src);
                    //int keySize = rsa.KeySize / 8; // in bytes
                    //int blockSize = keySize - 42; // 最大明文长度(OAEP SHA256)= keySize - 2 * hashLength = 256 - 2*32 = 192
                    int chunkSize = 117; // Java 示例中使用的是 117 字节,对应 1024 bit 密钥 + SHA-256 OAEP
                    byte[] encryptedData;

                    using (var memoryStream = new MemoryStream())
                    {
                        int offset = 0;

                        while (offset < dataToEncrypt.Length)
                        {
                            int remaining = dataToEncrypt.Length - offset;
                            int blockLen = Math.Min(chunkSize, remaining);
                            byte[] block = new byte[blockLen];
                            Array.Copy(dataToEncrypt, offset, block, 0, blockLen);

                            byte[] encryptedBlock = rsa.Encrypt(block, RSAEncryptionPadding.OaepSHA256);
                            memoryStream.Write(encryptedBlock, 0, encryptedBlock.Length);

                            offset += blockLen;
                        }

                        encryptedData = memoryStream.ToArray();
                    }

                    return Convert.ToBase64String(encryptedData);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("加密失败:" + ex.Message);
                throw;
            }
        }


    }
}

Java那边的部分代码:

public class Encryption {
	private static final int MAX_ENCRYPT_BLOCK = 117;

	public static String symEncrypt(String strkey, String src) throws Exception {
		String target = null;

		try {
			Key key = KeysFactory.getSymKey(strkey);
			Cipher cipher = Cipher.getInstance("AES/CTR/NoPadding");
			IvParameterSpec iv = new IvParameterSpec(strkey.substring(0, 16).getBytes());
			cipher.init(1, key, iv);
			byte[] encodeResult = cipher.doFinal(src.getBytes(StandardCharsets.UTF_8));
			target = Base64Util.encryptBASE64(encodeResult);
			return target;
		} catch (NoSuchPaddingException | UnsupportedEncodingException | InvalidKeyException | IllegalBlockSizeException
				| BadPaddingException | NoSuchAlgorithmException var7) {
			Logger.error(var7);
			throw new Exception("加密失败" + var7.getMessage());
		}
	}

	public static String pubEncrypt(String pubKey, String src) throws Exception {
		String target = null;
		ByteArrayOutputStream out = null;

		try {
			Key key = KeysFactory.getPublicKey(pubKey);
			Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding");
			cipher.init(1, key,
					new OAEPParameterSpec("SHA-256", "MGF1", new MGF1ParameterSpec("SHA-256"), PSpecified.DEFAULT));
			byte[] data = src.getBytes();
			int inputLen = data.length;
			out = new ByteArrayOutputStream();
			int offSet = 0;

			for (int i = 0; inputLen - offSet > 0; offSet = i * 117) {
				byte[] cache;
				if (inputLen - offSet > 117) {
					cache = cipher.doFinal(data, offSet, 117);
				} else {
					cache = cipher.doFinal(data, offSet, inputLen - offSet);
				}

				out.write(cache, 0, cache.length);
				++i;
			}

			target = Base64Util.encryptBASE64(out.toByteArray());
		} catch (NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException
				| NoSuchAlgorithmException var14) {
			Logger.error(var14);
			throw new Exception("加密失败" + var14.getMessage());
		} finally {
			if (out != null) {
				out.close();
			}

		}

		return target;
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值