ОБНОВЛЕНИЕ С ЧИТАТЕЛЕМ, чтобы узнать больше внутри:
Это работает:
var privateKeyPath = @"C:\foo\DKIM Private Key.txt";
var signer = new DkimSigner(
privateKeyPath,
mailKitConfiguration.Domain,
mailKitConfiguration.Selector);
signer.Sign(message, headersToSign);
Как это может работать с использованием Stream вместо этого? - Я даже не знаю, моя privateKey
переменная или моя memory Stream
причина моих проблем. Я пробовал это:
var privateKey = @"-----BEGIN RSA PRIVATE KEY-----MICESDABCDEF..............KBgQDa3-----END RSA PRIVATE KEY-----";
var privateKeyBytes = Encoding.ASCII.GetBytes(privateKey);
using (var memory = new MemoryStream(privateKeyBytes))
{
using (var reader = new StreamReader(memory))
{
var test1 = reader.ReadLine(); // test1: "-----BEGIN RSA PRIVATE KEY-----\nMIICXQIBAAKBgQDa38lnCp4wTcuk0Dkl6zjbc9hkeTCLFa0F4pc7XCsDj......."
var test2 = reader.ReadLine(); // test2: empty
var test3 = reader.ReadLine(); // test3: empty
}
memory.Position = 0;
var signer = new DkimSigner(
memory,
mailKitConfiguration.Domain,
mailKitConfiguration.Selector
);
signer.Sign(message, headersToSign);
}
Сообщение:
System.FormatException: Private key not found.
Трассировки стека:
at MimeKit.Cryptography.DkimSignerBase.LoadPrivateKey(Stream stream)
at MimeKit.Cryptography.DkimSigner..ctor(Stream stream, String domain, String selector,
DkimSignatureAlgorithm algorithm)
Когда я отлаживаю, позиция уже равна «0» до «memory.Position = 0;».
Позиция потока памяти перемещается в конец данных после записи. Тогда, если вы прочитаете, все, что вы получите, это EOS. Вы должны переместить позицию в ноль перед чтением (после записи). Поток памяти также недействителен за пределами используемого блока.
Хорошо, это имеет смысл, но я не уверен, какую именно строку вы имеете в виду. Вы имеете в виду вот так, где я добавил memory.Position = 0;
между открывающей скобкой и перед var signer...
? Потому что я пробовал это без везения. Это что-то другое?
После следующего: var memory = new MemoryStream (privateKeyBytes)
На данный момент я могу немного подозревать, что у вас есть действительный закрытый ключ. Как был создан этот pem-файл?
@PresidentJamesK.Polk Это действительно так, за последние недели я отправил более 50 писем. Вот почему я предоставил свое рабочее решение, чтобы исключить его. Я думаю, что проблема в том, что байты не разбиты на мелкие кусочки, как в каждой строке файла.
Вам не нужно сбрасывать позицию потока на 0, конструктор MemoryStream(byte[])
уже начинается с 0.
Вам нужны символы новой строки в вашем ключе: -----BEGIN RSA PRIVATE KEY-----\r\n(data)\r\n---
.
Хорошо, я попытаюсь. Это была моя первая мысль, когда я погуглил, кто-то сказал, что это не сработает, поэтому я на самом деле никогда не пробовал.
Спасибо, но я все еще получаю ту же ошибку. Я пробовал как с "\n" в самом конце, так и без него для длинной строки, так как не был уверен, что включаю ее.
Да, PemReader ожидает, что ключ формата PEM будет иметь определенный формат: github.com/bcgit/bc-java/blob/… который будет работать только в том случае, если включены разрывы строк, как предлагается.
Ладно круто, удалю последний \n
. Я только попробовал, потому что с первой попытки не получилось. Может быть, мне нужно \r\n
вместо этого? Я еще раз пройдусь по всем своим \n
, но они должны быть в нужном месте.
@CodeCaster Как вы думаете, это может быть что-то еще, например. как Encoding.ASCII.GetBytes(privateKey)
? :/
@radbyx хорошо, что StreamReader, используемый в коде, предполагает UTF-8, который является надмножеством ASCII, так что это должно просто работать, поскольку вы используете только символы, которые лежат в диапазоне кодовых точек ASCII. Вы можете проверить свой ввод и вывод, используя StreamReader(memory)
и трижды вызвав ReadLine. И только после чтения или записи нужно сбросить его положение.
@CodeCaster Пожалуйста, посмотрите мое обновление, читатель показывает, что «\n» не работает. :/
@radbyx это потому, что вы определяете строку @verbatim. Вам не нужен @
.
@jdweng Все та же ошибка. Я также обновил код. Вы имеете в виду вот так? Я новичок в потоках.