首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用yubikey SDK for .NET解密文本?

如何使用yubikey SDK for .NET解密文本?
EN

Stack Overflow用户
提问于 2021-10-16 20:19:43
回答 1查看 103关注 0票数 0

我正在尝试使用yubikey来加密/解密我的应用程序中的字符串。到目前为止,我已经写了一些用于测试的方法。我的代码基于我在官方存储库中找到的示例:Yubito.YubiKey/ examples /PivSampleCode/。

但是,我不能解密任何东西。我得到一个InvalidOperationException:未找到引用的数据或引用的数据。

我还注意到,每次运行该方法时,加密的字符串都会更改,对吗?我需要能够使用内部私钥进行加密并共享公钥。但是,如果每次密钥对的更改对我来说都是一个大问题。你们有什么建议吗?

以下是我使用的代码,加密但不解密:

代码语言:javascript
复制
using System.Diagnostics;    
using System.Security.Cryptography;
using Yubico.YubiKey;
using Yubico.YubiKey.Cryptography;
using Yubico.YubiKey.Piv;
using Yubico.Core.Buffers;

private static bool KeyCollectorPrompt(KeyEntryData keyEntryData)
        {
            switch(keyEntryData.Request)
            {
                case KeyEntryRequest.AuthenticatePivManagementKey:
                    keyEntryData.SubmitValue(Hex.HexToBytes("010203040506070801020304050607080102030405060708").ToArray());
                    return true;
                case KeyEntryRequest.VerifyPivPin:
                    keyEntryData.SubmitValue(Encoding.ASCII.GetBytes("123456"));
                    return true;
            }
            return false;
        }

private void testEncryptionButton1_Click(object sender, EventArgs e)
        {
            IYubiKeyDevice yubikey = YubiKeyDevice.FindAll().First();
            string plainText = "helloWorld";
            byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText);
            byte[] decryptedData = Array.Empty<byte>();
            byte[] encryptedDataBytes = Array.Empty<byte>();
            using (PivSession pivSession = new PivSession(yubikey))
            {
                try
                {
                    pivSession.KeyCollector = KeyCollectorPrompt;
                    PivMetadata pivMetadata = pivSession.GetMetadata(PivSlot.Attestation);
                    PivPublicKey pivPublicKey = pivMetadata.PublicKey;
                    using (RSA rsa = (RSA)KeyConverter.GetDotNetFromPivPublicKey(pivPublicKey))
                    {
                        encryptedDataBytes = rsa.Encrypt(plainTextBytes, RSAEncryptionPadding.OaepSHA256);
                        Debug.WriteLine("Encrypted Data: " + Convert.ToBase64String(encryptedDataBytes));
                        rsa.Dispose();
                    }
                    //this is the line that generates the exception, I tried with different slots.
                    byte[] rawDecryptedData = pivSession.Decrypt(0x9D, encryptedDataBytes);
                    int digestAlgorith = RsaFormat.Sha256;
                    RsaFormat.TryParsePkcs1Oaep(rawDecryptedData, digestAlgorith, out decryptedData);
                    Debug.WriteLine("Decrypted Data: " + Encoding.ASCII.GetString(decryptedData));

                    pivSession.Dispose();
                }
                catch (Exception ex)
                {
                    Debug.WriteLine(ex.ToString());
                }
            }
        }

private void testEncryptionButton2_Click(object sender, EventArgs e)
        {
            if (yubikeysFoundComboBox.SelectedIndex == -1)
            {
                MessageBox.Show("You must select a Yubikey");
                yubikeysFoundComboBox.Focus();
                return;
            }
            IYubiKeyDevice yubikey;
            int serialNumber = Convert.ToInt32(yubikeysFoundComboBox.SelectedItem);
            if (!YubiKeyDevice.TryGetYubiKey(serialNumber, out yubikey))
            {
                MessageBox.Show("ERROR: Unable to set the selected Yubikey");
                yubikeysFoundComboBox.SelectedIndex = -1;
                yubikeysFoundComboBox.Focus();
                return;
            }
            yubikey.SetEnabledNfcCapabilities(YubiKeyCapabilities.Piv);
            Debug.WriteLine(yubikey.EnabledNfcCapabilities);
            Task.Delay(1000).Wait();
            yubikey = YubiKeyDevice.FindAll().First(y => y.SerialNumber == serialNumber) as IYubiKeyDevice;
            Debug.WriteLine(yubikey.EnabledNfcCapabilities);
            using (PivSession pivSession = new PivSession(yubikey))
            {
                try
                {
                    pivSession.KeyCollector = KeyCollectorPrompt;
                    //PivPublicKey publicKey = pivSession.GenerateKeyPair(PivSlot.Authentication, PivAlgorithm.Rsa2048);
                    
                    //Debug.WriteLine("Public Key: " + Hex.BytesToHex(publicKey.PivEncodedPublicKey.ToArray()));
                    //Task.Delay(200).Wait();

                    string plainText = "helloWorld";
                    byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText);

                    byte[] signature;
                    int keySizeInBits = PivAlgorithm.Rsa2048.KeySizeBits();
                    byte[] digest = MessageDigestOperations.ComputeMessageDigest(plainTextBytes, HashAlgorithmName.SHA256);
                    int digestAlgorithm = RsaFormat.Sha256;
                    digest = RsaFormat.FormatPkcs1Pss(digest, digestAlgorithm, keySizeInBits);
                    string encryptedData;
                    signature = pivSession.Sign(0x9A, digest);
                    encryptedData = Convert.ToBase64String(signature);
                    Debug.WriteLine("Encrypted data: " + encryptedData);
                    Task.Delay(100).Wait();
                    //This is the line that throws the exception
                    byte[] rawDecryptedData = pivSession.Decrypt(0x9D, digest);
                    byte[] decryptedData = Array.Empty<byte>();
                    RsaFormat.TryParsePkcs1Decrypt(rawDecryptedData, out decryptedData);
                    Debug.WriteLine("Decrypted data: " + Encoding.UTF8.GetString(decryptedData));

                    pivSession.Dispose();
                }
                catch(Exception ex)
                {
                    Debug.WriteLine(ex.ToString());
                }
            }

        }

你们有什么建议吗?

提前感谢!

EN

回答 1

Stack Overflow用户

发布于 2021-10-25 08:08:00

源代码的问题是变量digest用于解密:

摘要rawDecryptedData = pivSession.Decrypt(0x9D,摘要);

相反,应该使用变量encryptedData进行解密,如下所示:

byte[] rawDecryptedData = pivSession.Decrypt(0x9D,encryptedData);

加密数据改变的原因是,对于每个加密操作,根据RSAEncryptionPadding.OaepSHA256用随机数据填充加密数据。RSA中的YubiKey公钥和私钥是静态的,不会更改。数据使用公共RSA密钥加密,这是可以导出和共享的密钥。使用私钥对数据进行解密,并且该密钥永远不会离开YubiKey。它受必须为解密操作输入的PIN码的保护。

前面关于从不使用RSA加密任意纯文本数据的注释是正确的。使用RSA加密的数据的最大限制非常有限。例如,对于具有PKCS #1的RSA2048,最大数据大小变为2048/8 - 11= 256 -11= 245。此外,RSA的性能比AES慢得多。相反,建议将RSA非对称加密与AES对称加密结合使用。这通常通过生成会话AES密钥并使用RSA加密密钥对其进行加密来完成。AES具有高性能加密大数据的优点,而RSA具有保护或共享AES会话密钥的优点。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69599266

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档