Используйте Stream для чтения закрытого ключа

ОБНОВЛЕНИЕ С ЧИТАТЕЛЕМ, чтобы узнать больше внутри:

Это работает:

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)

@jdweng Все та же ошибка. Я также обновил код. Вы имеете в виду вот так? Я новичок в потоках.

radbyx 18.12.2020 14:24

Когда я отлаживаю, позиция уже равна «0» до «memory.Position = 0;».

radbyx 18.12.2020 14:25

Позиция потока памяти перемещается в конец данных после записи. Тогда, если вы прочитаете, все, что вы получите, это EOS. Вы должны переместить позицию в ноль перед чтением (после записи). Поток памяти также недействителен за пределами используемого блока.

jdweng 18.12.2020 14:41

Хорошо, это имеет смысл, но я не уверен, какую именно строку вы имеете в виду. Вы имеете в виду вот так, где я добавил memory.Position = 0; между открывающей скобкой и перед var signer...? Потому что я пробовал это без везения. Это что-то другое?

radbyx 18.12.2020 14:52

После следующего: var memory = new MemoryStream (privateKeyBytes)

jdweng 18.12.2020 15:11

На данный момент я могу немного подозревать, что у вас есть действительный закрытый ключ. Как был создан этот pem-файл?

President James K. Polk 18.12.2020 16:16

@PresidentJamesK.Polk Это действительно так, за последние недели я отправил более 50 писем. Вот почему я предоставил свое рабочее решение, чтобы исключить его. Я думаю, что проблема в том, что байты не разбиты на мелкие кусочки, как в каждой строке файла.

radbyx 18.12.2020 16:20
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
7
610
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вам не нужно сбрасывать позицию потока на 0, конструктор MemoryStream(byte[]) уже начинается с 0.

Вам нужны символы новой строки в вашем ключе: -----BEGIN RSA PRIVATE KEY-----\r\n(data)\r\n---.

Хорошо, я попытаюсь. Это была моя первая мысль, когда я погуглил, кто-то сказал, что это не сработает, поэтому я на самом деле никогда не пробовал.

radbyx 18.12.2020 14:27

Спасибо, но я все еще получаю ту же ошибку. Я пробовал как с "\n" в самом конце, так и без него для длинной строки, так как не был уверен, что включаю ее.

radbyx 18.12.2020 14:43

Да, PemReader ожидает, что ключ формата PEM будет иметь определенный формат: github.com/bcgit/bc-java/blob/… который будет работать только в том случае, если включены разрывы строк, как предлагается.

Rob Evans 18.12.2020 14:49

Ладно круто, удалю последний \n. Я только попробовал, потому что с первой попытки не получилось. Может быть, мне нужно \r\n вместо этого? Я еще раз пройдусь по всем своим \n, но они должны быть в нужном месте.

radbyx 18.12.2020 14:55

@CodeCaster Как вы думаете, это может быть что-то еще, например. как Encoding.ASCII.GetBytes(privateKey)? :/

radbyx 18.12.2020 15:12

@radbyx хорошо, что StreamReader, используемый в коде, предполагает UTF-8, который является надмножеством ASCII, так что это должно просто работать, поскольку вы используете только символы, которые лежат в диапазоне кодовых точек ASCII. Вы можете проверить свой ввод и вывод, используя StreamReader(memory) и трижды вызвав ReadLine. И только после чтения или записи нужно сбросить его положение.

CodeCaster 18.12.2020 15:27

@CodeCaster Пожалуйста, посмотрите мое обновление, читатель показывает, что «\n» не работает. :/

radbyx 18.12.2020 16:17

@radbyx это потому, что вы определяете строку @verbatim. Вам не нужен @.

CodeCaster 18.12.2020 17:12

Другие вопросы по теме