Tôi biết câu trả lời chính mà tôi có thể nhận được là tại sao bạn muốn làm điều đó?Sử dụng Khóa công cộng RSA để giải mã một chuỗi đã được mã hóa bằng Khóa riêng RSA
Thật không may mặc dù các cuộc biểu tình của tôi, tôi phải làm điều đó, mặc dù tôi biết nó có ý nghĩa rất ít.
Tôi có các hàm được viết bằng .Net để giải mã bằng khóa riêng, mã hóa bằng khóa công khai. Tôi cũng RSA ký và xác minh và có một sự hiểu biết hợp lý về cách làm việc này tất cả tôi nghĩ.
Tôi hiện đang được gửi một giá trị được mã hóa RSA bằng khóa riêng tư mà tôi cho rằng sẽ lấy được giá trị có thể sử dụng bằng cách giải mã bằng khóa công khai.
Tôi dường như không thể tìm ra cách thực hiện việc này. Tôi có phải là một thằng ngốc không? Đây có phải là điều bình thường để làm không?
Tôi được người gửi cho tôi biết rằng giá trị này không có vấn đề gì trong PHP. Tôi chưa biết và chưa sử dụng PHP. Tôi không thể tìm thấy thư viện để thực hiện nó bằng bất kỳ ngôn ngữ chính nào mà tôi biết, ví dụ: C++, Java, C#. Máy chủ tôi đang sử dụng .Net.
Tôi hy vọng ai đó có thể giúp tôi.
Sẽ là tuyệt vời nếu có một số giải pháp hợp lý bên cạnh việc cầu xin họ thay đổi những gì họ đang làm.
Đây là phương pháp của tôi (cập nhật từ một xấu trước đây của tôi như đã chỉ ra bởi Iridium) nhưng khi tôi cố gắng để giải mã giá trị tôi nhận được một ngoại lệ
"Xảy ra lỗi lầm trong khi giải mã đệm OAEP."
Nếu tôi sử dụng rsa.Decrypt (byte, false) Tôi nhận được ngoại lệ khóa không hợp lệ.
public static string DecryptUsingPublic(string dataEncrypted, string publicKey)
{
if (dataEncrypted == null) throw new ArgumentNullException("dataEncrypted");
if (publicKey == null) throw new ArgumentNullException("publicKey");
try
{
RSAParameters _publicKey = LoadRsaPublicKey(publicKey, false);
RSACryptoServiceProvider rsa = InitRSAProvider(_publicKey);
byte[] bytes = Convert.FromBase64String(dataEncrypted);
byte[] decryptedBytes = rsa.Decrypt(bytes, true);
ArrayList arrayList = new ArrayList();
arrayList.AddRange(decryptedBytes);
return Encoding.UTF8.GetString(decryptedBytes);
}
catch
{
return null;
}
}
private static RSAParameters LoadRsaPublicKey(String publicKeyFilePath, Boolean isFile)
{
RSAParameters RSAKeyInfo = new RSAParameters();
byte[] pubkey = ReadFileKey(publicKeyFilePath, "PUBLIC KEY", isFile);
byte[] SeqOID = { 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00 };
byte[] seq = new byte[15];
// --------- Set up stream to read the asn.1 encoded SubjectPublicKeyInfo blob ------
MemoryStream mem = new MemoryStream(pubkey);
BinaryReader binr = new BinaryReader(mem); //wrap Memory Stream with BinaryReader for easy reading
byte bt = 0;
ushort twobytes = 0;
try
{
twobytes = binr.ReadUInt16();
if (twobytes == 0x8130) //data read as little endian order (actual data order for Sequence is 30 81)
binr.ReadByte(); //advance 1 byte
else if (twobytes == 0x8230)
binr.ReadInt16(); //advance 2 bytes
else
return RSAKeyInfo;
seq = binr.ReadBytes(15); //read the Sequence OID
if (!CompareBytearrays(seq, SeqOID)) //make sure Sequence for OID is correct
return RSAKeyInfo;
twobytes = binr.ReadUInt16();
if (twobytes == 0x8103) //data read as little endian order (actual data order for Bit String is 03 81)
binr.ReadByte(); //advance 1 byte
else if (twobytes == 0x8203)
binr.ReadInt16(); //advance 2 bytes
else
return RSAKeyInfo;
bt = binr.ReadByte();
if (bt != 0x00) //expect null byte next
return RSAKeyInfo;
twobytes = binr.ReadUInt16();
if (twobytes == 0x8130) //data read as little endian order (actual data order for Sequence is 30 81)
binr.ReadByte(); //advance 1 byte
else if (twobytes == 0x8230)
binr.ReadInt16(); //advance 2 bytes
else
return RSAKeyInfo;
twobytes = binr.ReadUInt16();
byte lowbyte = 0x00;
byte highbyte = 0x00;
if (twobytes == 0x8102) //data read as little endian order (actual data order for Integer is 02 81)
lowbyte = binr.ReadByte(); // read next bytes which is bytes in modulus
else if (twobytes == 0x8202)
{
highbyte = binr.ReadByte(); //advance 2 bytes
lowbyte = binr.ReadByte();
}
else
return RSAKeyInfo;
byte[] modint = { lowbyte, highbyte, 0x00, 0x00 }; //reverse byte order since asn.1 key uses big endian order
int modsize = BitConverter.ToInt32(modint, 0);
byte firstbyte = binr.ReadByte();
binr.BaseStream.Seek(-1, SeekOrigin.Current);
if (firstbyte == 0x00)
{ //if first byte (highest order) of modulus is zero, don't include it
binr.ReadByte(); //skip this null byte
modsize -= 1; //reduce modulus buffer size by 1
}
byte[] modulus = binr.ReadBytes(modsize); //read the modulus bytes
if (binr.ReadByte() != 0x02) //expect an Integer for the exponent data
return RSAKeyInfo;
int expbytes = (int)binr.ReadByte(); // should only need one byte for actual exponent data (for all useful values)
byte[] exponent = binr.ReadBytes(expbytes);
RSAKeyInfo.Modulus = modulus;
RSAKeyInfo.Exponent = exponent;
return RSAKeyInfo;
}
catch (Exception)
{
return RSAKeyInfo;
}
finally { binr.Close(); }
//return RSAparams;
}
private static RSACryptoServiceProvider InitRSAProvider(RSAParameters rsaParam)
{
//
// Initailize the CSP
// Supresses creation of a new key
//
CspParameters csp = new CspParameters();
//csp.KeyContainerName = "RSA Test (OK to Delete)";
const int PROV_RSA_FULL = 1;
csp.ProviderType = PROV_RSA_FULL;
const int AT_KEYEXCHANGE = 1;
// const int AT_SIGNATURE = 2;
csp.KeyNumber = AT_KEYEXCHANGE;
//
// Initialize the Provider
//
RSACryptoServiceProvider rsa =
new RSACryptoServiceProvider(csp);
rsa.PersistKeyInCsp = false;
//
// The moment of truth...
//
rsa.ImportParameters(rsaParam);
return rsa;
}
private static int GetIntegerSize(BinaryReader binr)
{
byte bt = 0;
byte lowbyte = 0x00;
byte highbyte = 0x00;
int count = 0;
bt = binr.ReadByte();
if (bt != 0x02) //expect integer
return 0;
bt = binr.ReadByte();
if (bt == 0x81)
count = binr.ReadByte(); // data size in next byte
else
if (bt == 0x82)
{
highbyte = binr.ReadByte(); // data size in next 2 bytes
lowbyte = binr.ReadByte();
byte[] modint = { lowbyte, highbyte, 0x00, 0x00 };
count = BitConverter.ToInt32(modint, 0);
}
else
{
count = bt; // we already have the data size
}
while (binr.ReadByte() == 0x00)
{ //remove high order zeros in data
count -= 1;
}
binr.BaseStream.Seek(-1, SeekOrigin.Current); //last ReadByte wasn't a removed zero, so back up a byte
return count;
}
private static bool CompareBytearrays(byte[] a, byte[] b)
{
if (a.Length != b.Length)
return false;
int i = 0;
foreach (byte c in a)
{
if (c != b[i])
return false;
i++;
}
return true;
}
Hai phương pháp trên InitRSAProvider và LoadRsaPublicKey đã được đưa ra hướng dẫn để cho phép các khóa PEM sử dụng với chuỗi .Net.
Nói gì? Đó là chính xác những gì các thuật toán được cho là phải làm. Giải mã bằng khóa riêng tư được mã hóa bằng khóa công khai tương ứng. Hoặc là bạn đang bối rối thời gian lớn hay tôi! C# hỗ trợ hoàn toàn RSA :) –
Xin lỗi. Đã chỉnh sửa câu hỏi của tôi. Tôi đã viết nó hoàn toàn sai. Brain bắt đầu tranh giành một chút vào thứ Sáu. –
Bạn không thể tìm ra điều gì? Bạn nói rằng bạn đã có chức năng để giải mã bằng cách sử dụng một khóa công khai. – James