菜鸟教程小白 发表于 2022-12-12 20:24:32

c# - IOS公钥加密和C#解密


                                            <p><p>我试图在 IOS 中加密一个字符串,然后在 C# 中解密它。</p>

<p>我已经能够仅使用 C# 加密和解密字符串,但 IOS 端似乎不正确。</p>

<p>在 C# 中,我使用它来解密字符串:</p>

<pre><code>private static RSACryptoServiceProvider _rsa;
private const int PROVIDER_RSA_FULL = 1;
private const string CONTAINER_NAME = &#34;KeyContainer&#34;;
private const string PROVIDER_NAME = &#34;Microsoft Strong Cryptographic Provider&#34;;

private static void _AssignParameter()
{
    CspParameters cspParams;
    cspParams = new CspParameters(PROVIDER_RSA_FULL, PROVIDER_NAME, CONTAINER_NAME);
    cspParams.Flags = CspProviderFlags.UseMachineKeyStore;
    CryptoKeyAccessRule rule = new CryptoKeyAccessRule(&#34;everyone&#34;, CryptoKeyRights.FullControl, AccessControlType.Allow);
    cspParams.CryptoKeySecurity = new CryptoKeySecurity();
    cspParams.CryptoKeySecurity.SetAccessRule(rule);

    _rsa = new RSACryptoServiceProvider(cspParams);
    _rsa.PersistKeyInCsp = false;
}

private static void decrypt(byte[] data, byte[] PrivateKey)
{
    _AssignParameter();
    _rsa.ImportCspBlob(PrivateKey);
    _rsa.Decrypt(data, false);
}
</code></pre>

<p>上面的 C# 代码只是一个片段,并不是完整的代码。</p>

<p>看起来很简单,这是我用于IOS的,</p>

<pre><code>      //get nsdata from mod and exp
      NSString *mod = publicKeyObjects;
      NSData *pubKeyModData= ; //172 bytes
      NSString *exp = publicKeyObjects;
      NSData *pubKeyExpData= ;

      //create nsdata key with mod and exp
      NSMutableArray *publicKeyArray = [ init];
      ;
      ;
      NSData *publicKeyData = ;

      //add the key to the keychain and create a ref
      NSData* peerTag = [@&#34;KeyContainer&#34; dataUsingEncoding:NSUTF8StringEncoding];
      NSMutableDictionary *publicKey = [ init];
      ;
      ;
      ;
      SecItemDelete((__bridge CFDictionaryRef)publicKey);

      CFTypeRef persistKey = nil;

      // Add persistent version of the key to system keychain
      ;
      ;
       forKey:(__bridge id)kSecReturnPersistentRef];
      OSStatus secStatus = SecItemAdd((__bridge CFDictionaryRef)publicKey, &amp;persistKey);
      if (persistKey != nil)
            CFRelease(persistKey);

      // Now fetch the SecKeyRef version of the key
      SecKeyRef keyRef = nil;

      ;
      ;
       forKey:(__bridge id)kSecReturnRef];
      ;
      secStatus = SecItemCopyMatching((__bridge CFDictionaryRef)publicKey,(CFTypeRef *)&amp;keyRef);


      NSData* stringData = [@&#34;string to encrypt&#34; dataUsingEncoding:NSUTF8StringEncoding];
      NSData* encryptedString = ;


-(NSData *)encrypt:(NSData *)Bytes usingKey:(SecKeyRef)key
{
    size_t cipherBufferSize = SecKeyGetBlockSize(key); //returns 172
    uint8_t *cipherBuffer = NULL;
    cipherBuffer = malloc(cipherBufferSize * sizeof(uint8_t));
    memset((void *)cipherBuffer, 0x0, cipherBufferSize);
    OSStatus status = SecKeyEncrypt(key, kSecPaddingNone,
                                    (const uint8_t *),
                                    , cipherBuffer,
                                    &amp;cipherBufferSize);
    if (status == noErr)
    {
      NSData *encryptedBytes = [
                                 initWithBytes:(const void *)cipherBuffer
                                 length:cipherBufferSize];
      if (cipherBuffer)
      {
            free(cipherBuffer);
      }
      NSLog(@&#34;Encrypted text (%d bytes): %@&#34;, , );
      return encryptedBytes;
    }
    else
    {
      NSLog(@&#34;encrypt:usingKey: Error: %d&#34;, (int)status);
      return nil;
    }
}
</code></pre>

<p>所以一旦我尝试解密我得到的 C# 代码中的数据:</p>

<p><code>要解密的数据超过了这个模数的最大值 128 字节。</code></p>

<p>我用谷歌搜索了这个错误,发现它与 keysize 有关系,但是我用 IOS 导入模数后的 keysize 是 172 字节。</p>

<p>但我只是用 <code>_rsa.ToXmlString(false);</code></p> 导出公钥

<p><em><strong>编辑</strong></em></p>

<p>我想我修正了自己的错误,</p>

<pre><code>    //get nsdata from mod and exp
    NSString *mod = publicKeyObjects;
    NSData *pubKeyModData= ;
    NSString *exp = publicKeyObjects;
    NSData *pubKeyExpData= ;
</code></pre>

<p>这是直接用 utf8 转换 base64 字符串,它应该使用:</p>

<pre><code>NSData *pubKeyModData = [ initWithBase64EncodedString:mod options:0];
NSData *pubKeyExpData = [ initWithBase64EncodedString:exp options:0];
</code></pre>

<p>现在我收到另一个错误<code>Bad Data</code></p>

<p>有人可以在这里指出我正确的方向吗?我也为所有代码道歉。我只是不知道问题出在哪里。</p></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>回答了我自己的问题,</p>

<pre><code>//get nsdata from mod and exp
NSString *mod = publicKeyObjects;
NSData *pubKeyModData= ;
NSString *exp = publicKeyObjects;
NSData *pubKeyExpData= ;
</code></pre>

<p>变成了这样:</p>

<pre><code>//get nsdata from mod and exp
NSString *mod = publicKeyObjects;
NSData *pubKeyModData = [ initWithBase64EncodedString:mod options:0];
NSString *exp = publicKeyObjects;
NSData *pubKeyExpData = [ initWithBase64EncodedString:exp options:0];
</code></pre>

<p>那么这个</p>

<pre><code>OSStatus status = SecKeyEncrypt(key, kSecPaddingNone,
                              (const uint8_t *),
                              , cipherBuffer,
                              &amp;cipherBufferSize);
</code></pre>

<p>成为:</p>

<pre><code>OSStatus status = SecKeyEncrypt(key, kSecPaddingPKCS1,
                              (const uint8_t *),
                              , cipherBuffer,
                              &amp;cipherBufferSize);
</code></pre>

<p>简单的配置修复。</p></p>
                                   
                                                <p style="font-size: 20px;">关于c# - IOS公钥加密和C#解密,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/22450098/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/22450098/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: c# - IOS公钥加密和C#解密