(2025-01-24 16:06:22 отредактировано dahilu)

c#. Рутокен 3.0. Ubuntu 20 Value cannot be null. (Parameter 'source')

Добрый день.

Возникает Exception при подписывании документа PKCS7Sign().

Value cannot be null. (Parameter 'source')

Использую NuGet
Aktiv.RutokenPkcs11Interop 2.0.11
Pkcs11Interop 4.1.1

Через браузер, на демо портале все работает.



Подскажите, пожалуйста, в чем причина?

        public byte[] Sign(string FilePath, bool isSignAttached = true)
        {
            Net.Pkcs11Interop.HighLevelAPI.ObjectHandle certificate = new();

            Net.Pkcs11Interop.HighLevelAPI.ObjectHandle privateKey = new();

            try
            {
                string mydll = @"./librtpkcs11ecp.so";                

                Console.WriteLine($"mydll: {mydll}");

                using (var pkcs11 = new Pkcs11(mydll, AppType.SingleThreaded))
                {

                    Slot slot = Helpers.GetUsableSlot(pkcs11);                                      // Find first slot with token present

                    using (Session session = slot.OpenSession(SessionType.ReadWrite))
                    {
                        session.Login(CKU.CKU_USER, _password);

                        var pairs = GetCertAndKey(session, _ckaId);                        

                        byte[] ar = File.ReadAllBytes(FilePath);

                        return session.PKCS7Sign(ar, pairs[0].cert, pairs[0].key, null, SampleConstants.UseHardwareHash);       // Подпись данных c присоединенной подписью

                    }
                }
            }

Re: c#. Рутокен 3.0. Ubuntu 20 Value cannot be null. (Parameter 'source')

dahilu, Добрый день!
Уточните пожалуйста, какие сертификаты вы используете для подписания?

Re: c#. Рутокен 3.0. Ubuntu 20 Value cannot be null. (Parameter 'source')

Филиппов Никита пишет:

dahilu, Добрый день!
Уточните пожалуйста, какие сертификаты вы используете для подписания?


Использую тестовые сертификаты и тестовые ключевые пары. Созданы через web портал.

При работе на Windows - никаких проблем не возникает.

Только на Linux есть ошибка. Ну и как говорил, через ваше web демо, на Linux, все отрабатывает без ошибок.

https://forum.rutoken.ru/uploads/images/2025/01/7230ee13dee6490d1aac3a75f9be2dd7.png

Re: c#. Рутокен 3.0. Ubuntu 20 Value cannot be null. (Parameter 'source')

Добрый день.
Вы используете пример https://github.com/AktivCo/RutokenPkcs1 … 012-256.cs ?
Шаблон поиска ключа вы изменяли?

(2025-01-29 16:03:49 отредактировано dahilu)

Re: c#. Рутокен 3.0. Ubuntu 20 Value cannot be null. (Parameter 'source')

Аверченко Кирилл пишет:

Добрый день.
Вы используете пример https://github.com/AktivCo/RutokenPkcs1 … 012-256.cs ?
Шаблон поиска ключа вы изменяли?


Да пример этот.

Шаблон поиска ключа изменен на

        // Шаблон для поиска сертификата ключа подписи
        static readonly List<ObjectAttribute> CertificateAttributes = new List<ObjectAttribute>
        {
            new ObjectAttribute(CKA.CKA_CLASS, CKO.CKO_CERTIFICATE),
            new ObjectAttribute(CKA.CKA_TOKEN, true)
        };


        // Шаблон для поиска закрытого ключа ГОСТ Р 34.10-2012 (256 бит)
        static readonly List<ObjectAttribute> PrivateKeyAttributes = new List<ObjectAttribute>
        {
            new ObjectAttribute(CKA.CKA_CLASS, CKO.CKO_PRIVATE_KEY),
            new ObjectAttribute(CKA.CKA_TOKEN, true)
        };

Далее получаю по каждому объекту CKA_ID

Забираю сертификат и ключ по CKA_ID.

В подписе исполью их.



Есть уточнение.
Эта ошибка "Value cannot be null. (Parameter 'source')" возникает на виртуальной машине Ubuntu 20. Именно при выполнении метода PKCS7Sign().


Сегодня я проверил на физической машине с Linux Ubuntu 24.
Все сделал в соответствии инструкции:

https://dev.rutoken.ru/pages/viewpage.a … 0%BC%D0%B5


Результат:

При работе в командой строке все в порядке. Отрабатывают все команды (Подпись не пробовал, не разобрался).
Но при исполнении кода, возникает ошибка на стадии

new Pkcs11(mydll, AppType.SingleThreaded))


Ошибка:


"Unable to load shared library 'libdl' or one of its dependencies. In order to help diagnose loading problems, consider using a tool like strace. If you're using glibc, consider setting the LD_DEBUG environment variable: \n/usr/lib/RadioAccessCross/WebAPIProvider/libdl.so: cannot open shared object file: No such file or directory\n/usr/lib/RadioAccessCross/WebAPIProvider/liblibdl.so: cannot open shared object file: No such file or directory\n/usr/lib/RadioAccessCross/WebAPIProvider/libdl: cannot open shared object file: No such file or directory\n/usr/lib/RadioAccessCross/WebAPIProvider/liblibdl: cannot open shared object file: No such file or directory\n"

(2025-01-29 15:52:56 отредактировано dahilu)

Re: c#. Рутокен 3.0. Ubuntu 20 Value cannot be null. (Parameter 'source')

С проблемой libdl.so разобрался. Нашел ее и положил ее рядом.
Информацию по ключам можно считать. Но при подписи - все равно

Value cannot be null. (Parameter 'source')


Помогите пожалуйста

Re: c#. Рутокен 3.0. Ubuntu 20 Value cannot be null. (Parameter 'source')

Если создать ключ и сертификат на токене с помощью тех же примеров, ошибка будет воспроизводиться?
Что вы передаете в функцию PKCS7Sign?

(2025-01-29 16:46:27 отредактировано dahilu)

Re: c#. Рутокен 3.0. Ubuntu 20 Value cannot be null. (Parameter 'source')

Аверченко Кирилл пишет:

Если создать ключ и сертификат на токене с помощью тех же примеров, ошибка будет воспроизводиться?
Что вы передаете в функцию PKCS7Sign?


Программно создать ключ еще не пробовал. Попробую.


Поиск сертификата и ключей:

        public List<(ObjectHandle cert, ObjectHandle key)> GetCertAndKey(Session Session, string CkaId)
        {
            List<(ObjectHandle cert, ObjectHandle key)> res = new();

            List<CKA> CKAAttributes = new List<CKA> { CKA.CKA_ID, CKA.CKA_CLASS, CKA.CKA_LABEL, CKA.CKA_PRIVATE };

            var certificates = Session.FindAllObjects(CertificateAttributes);               // Получить массив хэндлов сертификатов

            foreach (var cert in certificates)
            {
                var attr = Session.GetAttributeValue(cert, CKAAttributes);

                byte[] ar = attr[0].GetValueAsByteArray();

                string cka = BitConverter.ToString(ar);

                if (cka == CkaId)
                {
                    var keys = Session.FindAllObjects(PrivateKeyAttributes);               // Получить массив хэндлов приватных ключей

                    foreach (var key in keys)
                    {
                        var attr2 = Session.GetAttributeValue(key, CKAAttributes);

                        byte[] ar2 = attr[0].GetValueAsByteArray();

                        string cka2 = BitConverter.ToString(ar2);

                        if (cka2 == CkaId)
                        {
                            res.Add((cert, key));

                            break;
                        }
                    }

                    break;
                }
            }

            return res;
        }

Ищется все нормально. Находится 1 сертификат и один ключ.

Кусок кода для подписи:

var pairs = GetCertAndKey(session, _ckaId);  

if (pairs == null)
{
   throw new Exception($"Не найден сертификат или приватный ключ по указанному id: {_ckaId}");
}

byte[] ar = File.ReadAllBytes(FilePath);

                       
return session.PKCS7Sign(ar, pairs[0].cert, pairs[0].key, null, SampleConstants.UseHardwareHash);      


Вы можете прислать пример команды для подписи файла в cmd? Попробовать подписать через терминал

(2025-01-29 17:04:24 отредактировано dahilu)

Re: c#. Рутокен 3.0. Ubuntu 20 Value cannot be null. (Parameter 'source')

at System.Linq.ThrowHelper.ThrowArgumentNullException(ExceptionArgument argument)
   at System.Linq.Enumerable.Select[TSource,TResult](IEnumerable`1 source, Func`2 selector)
   at RutokenPkcs11Interop.HighLevelAPI.SessionExtensions.PKCS7Sign(Session session, Byte[] data, ObjectHandle certificate, ObjectHandle privateKey, UInt32[] certificates, UInt32 flags)
   at RutokenSigner.Signer.Sign(String FilePath, Boolean isSignAttached) in c:\Users\user\Documents\Git\r\RutokenSigner\Signer.cs:line 330

https://forum.rutoken.ru/uploads/images/2025/01/7caca5f712a0af1e9e97ab089458ab6a.png

Re: c#. Рутокен 3.0. Ubuntu 20 Value cannot be null. (Parameter 'source')

Можно попробовать подписывать с помощью openssl+rtengine https://dev.rutoken.ru/pages/viewpage.a … =180715764

dahilu пишет:

byte[] ar = File.ReadAllBytes(FilePath);

Файл присутствует?

Re: c#. Рутокен 3.0. Ubuntu 20 Value cannot be null. (Parameter 'source')

Аверченко Кирилл пишет:

Можно попробовать подписывать с помощью openssl+rtengine https://dev.rutoken.ru/pages/viewpage.a … =180715764

dahilu пишет:

byte[] ar = File.ReadAllBytes(FilePath);

Файл присутствует?


Да, массив байт ar заполняется.

Нужен ли какой то уровень доступа к файлу? Хотя сам процесс программы запущен по root

Re: c#. Рутокен 3.0. Ubuntu 20 Value cannot be null. (Parameter 'source')

Нашел я причину.


Не срабатывает этот код в вашей функции PKCS7Sign().

ulong[] certificates2 = ((IEnumerable<uint>)certificates).Select((Func<uint, ulong>)((uint cert) => cert)).ToArray();

Что надо передавать в параметр uint[] certificates ?





В вашем nuget RutokenPkcs11Interop 2.0.11.0 такой код:

    public static byte[] PKCS7Sign(this Net.Pkcs11Interop.HighLevelAPI.Session session, byte[] data, Net.Pkcs11Interop.HighLevelAPI.ObjectHandle certificate, Net.Pkcs11Interop.HighLevelAPI.ObjectHandle privateKey, uint[] certificates, uint flags)
    {
        if (Platform.UnmanagedLongSize == 4)
        {
            if (Platform.StructPackingSize == 0)
            {
                Net.Pkcs11Interop.HighLevelAPI40.ObjectHandle certificate2 = new Net.Pkcs11Interop.HighLevelAPI40.ObjectHandle((uint)certificate.ObjectId);
                Net.Pkcs11Interop.HighLevelAPI40.ObjectHandle privateKey2 = new Net.Pkcs11Interop.HighLevelAPI40.ObjectHandle((uint)privateKey.ObjectId);
                return session.HLA40Session.PKCS7Sign(data, certificate2, privateKey2, certificates, flags);
            }

            Net.Pkcs11Interop.HighLevelAPI41.ObjectHandle certificate3 = new Net.Pkcs11Interop.HighLevelAPI41.ObjectHandle((uint)certificate.ObjectId);
            Net.Pkcs11Interop.HighLevelAPI41.ObjectHandle privateKey3 = new Net.Pkcs11Interop.HighLevelAPI41.ObjectHandle((uint)privateKey.ObjectId);
            return session.HLA41Session.PKCS7Sign(data, certificate3, privateKey3, certificates, flags);
        }

        if (Platform.StructPackingSize == 0)
        {
            Net.Pkcs11Interop.HighLevelAPI80.ObjectHandle certificate4 = new Net.Pkcs11Interop.HighLevelAPI80.ObjectHandle((uint)certificate.ObjectId);
            Net.Pkcs11Interop.HighLevelAPI80.ObjectHandle privateKey4 = new Net.Pkcs11Interop.HighLevelAPI80.ObjectHandle((uint)privateKey.ObjectId);
            ulong[] certificates2 = ((IEnumerable<uint>)certificates).Select((Func<uint, ulong>)((uint cert) => cert)).ToArray();
            return session.HLA80Session.PKCS7Sign(data, certificate4, privateKey4, certificates2, flags);
        }

        Net.Pkcs11Interop.HighLevelAPI81.ObjectHandle certificate5 = new Net.Pkcs11Interop.HighLevelAPI81.ObjectHandle((uint)certificate.ObjectId);
        Net.Pkcs11Interop.HighLevelAPI81.ObjectHandle privateKey5 = new Net.Pkcs11Interop.HighLevelAPI81.ObjectHandle((uint)privateKey.ObjectId);
        ulong[] certificates3 = ((IEnumerable<uint>)certificates).Select((Func<uint, ulong>)((uint cert) => cert)).ToArray();
        return session.HLA81Session.PKCS7Sign(data, certificate5, privateKey5, certificates3, flags);
    }

Re: c#. Рутокен 3.0. Ubuntu 20 Value cannot be null. (Parameter 'source')

dahilu, добрый день.
Мы пока разбираемся, почему поведение этой функции отличается на Windows и Linux.
Можете описать свою задачу, чтобы мы смогли найти альтернативный вариант подписи?

Re: c#. Рутокен 3.0. Ubuntu 20 Value cannot be null. (Parameter 'source')

Аверченко Кирилл пишет:

dahilu, добрый день.
Мы пока разбираемся, почему поведение этой функции отличается на Windows и Linux.
Можете описать свою задачу, чтобы мы смогли найти альтернативный вариант подписи?



Добрый день.
Я уже сам разобрался.
Взял исходы из вашего репозитория на github.


Вам надо обновить nuget в nuget.ru

Re: c#. Рутокен 3.0. Ubuntu 20 Value cannot be null. (Parameter 'source')

dahilu, добрый день.

dahilu пишет:

Вам надо обновить nuget в nuget.ru

Подскажите, пожалуйста, о каком именно пакете идет речь?