title: How to generate a SHA256withRSA signature with the Windows CryptoAPI?
body: <p>I need to sign some data with the <code>SHA256withRSA</code> algorithm <code>(RSASSA-PKCS1-V1_5-SIGN</code> with <code>SHA-256</code> hash function) in Windows (and with <strong>Delphi</strong> or in <strong>c++</strong>). How can I do this? I want to use the Windows CryptoAPI.</p>
  <p>This is how I do to verify a signature :</p>
  <pre><code>function ALVerifyRSA256Signature(const aData: AnsiString; // bytes string
                                   const aSignature: AnsiString; // bytes string
                                   const aBase64PubKeyModulus: ansiString;
                                   Const aBase64PubKeyExponent: ansiString): boolean;
  
    {~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
    procedure _bigEndianToLittleEndian(var aArr: TBytes);
    var B: Byte;
        i,j: integer;
    begin
      J := Length(aArr) - 1;
      i := low(aArr);
      while i &lt; J do begin
        B := aArr[i];
        aArr[i] := aArr[j];
        aArr[j] := B;
        Dec(j);
        inc(i);
      end;
    end;
  
  var pModulus: TBytes;
      cbModulus: DWORD;
      pExponent: TBytes;
      cbExponent: DWORD;
      dwExponent: Dword;
      hProv: HCRYPTPROV;
      cbKeyBlob: DWord;
      pKeyBlob: Tbytes;
      pPublicKey: PUBLICKEYSTRUC;
      pRsaPubKey: RSAPUBKEY;
      hRSAKey: HCRYPTKEY;
      hHash: HCRYPTHASH;
      pSignature: TBytes;
  
  begin
  
    //init pModulus / cbModulus
    if not CryptStringToBinaryA(
             PansiChar(aBase64PubKeyModulus), // pszString: LPCSTR;
             length(aBase64PubKeyModulus), // cchString: DWORD;
             CRYPT_STRING_BASE64, // dwFlags: DWORD;
             nil, // pbBinary: pByte;
             @cbModulus, // pcbBinary: PDWORD;
             nil, // pdwSkip: PDWORD;
             nil) then raiseLastOsError; // pdwFlags: PDWORD
    setlength(pModulus, cbModulus);
    if not CryptStringToBinaryA(
             PansiChar(aBase64PubKeyModulus), // pszString: LPCSTR;
             length(aBase64PubKeyModulus), // cchString: DWORD;
             CRYPT_STRING_BASE64, // dwFlags: DWORD;
             @pModulus[0], // pbBinary: pByte;
             @cbModulus, // pcbBinary: PDWORD;
             nil, // pdwSkip: PDWORD;
             nil) then raiseLastOsError; // pdwFlags: PDWORD
    _bigEndianToLittleEndian(pModulus);
  
    //init pExponent / cbExponent
    if not CryptStringToBinaryA(
             PansiChar(aBase64PubKeyExponent), // pszString: LPCSTR;
             length(aBase64PubKeyExponent), // cchString: DWORD;
             CRYPT_STRING_BASE64, // dwFlags: DWORD;
             nil, // pbBinary: pByte;
             @cbExponent, // pcbBinary: PDWORD;
             nil, // pdwSkip: PDWORD;
             nil) then raiseLastOsError; // pdwFlags: PDWORD
    setlength(pExponent, cbExponent);
    if not CryptStringToBinaryA(
             PansiChar(aBase64PubKeyExponent), // pszString: LPCSTR;
             length(aBase64PubKeyExponent), // cchString: DWORD;
             CRYPT_STRING_BASE64, // dwFlags: DWORD;
             @pExponent[0], // pbBinary: pByte;
             @cbExponent, // pcbBinary: PDWORD;
             nil, // pdwSkip: PDWORD;
             nil) then raiseLastOsError; // pdwFlags: PDWORD
    _bigEndianToLittleEndian(pExponent);
    if cbExponent &gt; sizeof(dwExponent) then
      raise Exception.CreateFmt('Wrong exponent (%s)',[aBase64PubKeyExponent]);
    dwExponent := 0;
    move(pExponent[0], dwExponent, cbExponent);
  
    //acquire a handle to a particular key container
    if (not CryptAcquireContextA(@hProv, // phProv: PHCRYPTPROV;
                                 nil, // pszContainer: PAnsiChar;
                                 nil, // pszProvider: PAnsiChar;
                                 PROV_RSA_AES, // dwProvType: DWORD;
                                 CRYPT_VERIFYCONTEXT)) then raiselastOsError; // dwFlags: DWORD
    try
  
      // create the pKeyBlob
      // The data format is: PUBLICKEYSTRUC + RSAPUBKEY + key
      cbKeyBlob := sizeof(PUBLICKEYSTRUC) + sizeof(RSAPUBKEY) + cbModulus;
      setlength(pKeyBlob, cbKeyBlob);
  
      // Fill in the PUBLICKEYSTRUC
      pPublicKey.bType := PUBLICKEYBLOB;
      pPublicKey.bVersion := CUR_BLOB_VERSION;  // Always use this value.
      pPublicKey.reserved := 0;                 // Must be zero.
      pPublicKey.aiKeyAlg := CALG_RSA_KEYX;     // RSA public-key key exchange.
      Move(pPublicKey,pKeyBlob[0],sizeof(PUBLICKEYSTRUC));
  
      // Fill in the RSAPUBKEY
      pRsaPubKey.magic := RSA1;            // Public key.
      pRsaPubKey.bitlen := cbModulus * 8;  // Number of bits in the modulus.
      pRsaPubKey.pubexp := dwExponent;     // Exponent.
      Move(pRsaPubKey,pKeyBlob[sizeof(PUBLICKEYSTRUC)],sizeof(RSAPUBKEY));
  
      // Fill in the modulus
      Move(pModulus[0],pKeyBlob[sizeof(PUBLICKEYSTRUC)+sizeof(RSAPUBKEY)],cbModulus);
  
      // Now import the key.
      if not CryptImportKey(hProv, // hProv: HCRYPTPROV;
                            @pKeyBlob[0], // const pbData: PBYTE;
                            cbKeyBlob, // dwDataLen: DWORD;
                            0, // hPubKey: HCRYPTKEY;
                            0, // dwFlags: DWORD;
                            @hRSAKey) then raiseLastOsError; // phKey: PHCRYPTKEY
      try
  
        //initiates the hashing of a stream of data.
        if not (CryptCreateHash(hProv, // hProv: HCRYPTPROV;
                                CALG_SHA_256, // Algid: ALG_ID;
                                0, // hKey: HCRYPTKEY;
                                0, // dwFlags: DWORD;
                                @hHash)) then raiseLastOsError;
        try
  
          //adds data to a specified hash object.
          if not (CryptHashData(hHash, // hHash: HCRYPTHASH;
                                pbyte(aData), // const pbData: PBYTE;
                                length(aData), // dwDataLen: DWORD;
                                0)) then raiseLastOsError; // dwFlags: DWORD
  
          //verifies the signature
          setlength(pSignature, length(aSignature));
          Move(Pointer(aSignature)^, Pointer(pSignature)^, Length(aSignature));
          _bigEndianToLittleEndian(pSignature);
          if not CryptVerifySignatureA(hHash, // hHash: HCRYPTHASH;
                                       @pSignature[0], // const pbSignature: PBYTE;
                                       length(pSignature), // dwSigLen: DWORD;
                                       hRSAKey, // hPubKey: HCRYPTKEY;
                                       nil, // const sDescription: LPCSTR;
                                       0) then begin // dwFlags: DWORD)
            if HRESULT(GetLastError) = NTE_BAD_SIGNATURE then exit(False)
            else raiseLastOsError;
          end;
  
          //everything is ok
          Result := True;
  
        finally
          if not CryptDestroyHash(hHash) then raiseLastOsError;
        end;
  
      finally
        if not CryptDestroyKey(hRSAKey) then raiseLastOsError;
      end;
  
    finally
      if not CryptReleaseContext(hProv,0) then raiseLastOsError;
    end;
  end;
  </code></pre>
  <p>However in my case I need to sign some data using this private_key :</p>
  <pre><code>&quot;-----BEGIN PRIVATE KEY-----\xxxxxxxxxxxxxxxxxxx\n-----END PRIVATE KEY-----\n&quot;
  </code></pre>
  <p>How I can do?</p>