Quantcast
Channel: Rebex Q&A Forum - Recent questions and answers
Viewing all articles
Browse latest Browse all 3862

Answered: Signing/verifying a file with a PEM file

$
0
0

Rebex SFTP can do this, but it's not as straightforward as it seems.

  • Your priv.pem file is an encrypted private key, not a certificate. This means you have to use PrivateKeyInfo (part of Rebex.Common) or SshPrivateKey (part of Rebex.Networking) to load it.

  • Your private key seems to be an elliptic curve private key. To be able to use such keys on Windows Mobile 5 platform, you have to load an ECC plugin.

  • OpenSSL's dgst command uses ANS.1 encoded form of the signature (not a PKCS #7 SignedData blob). We don't have public API for this form yet. However, as a workaround, we can create a signature in the format used by SSH and convert that into the form used by OpenSSL's dgst.

  • I don't know which elliptic curve algorithm your key actually uses. Based on the choice of "SHA-512" hashing algorithm, I will assume it's a NIST P-521 curve key. If my guess is incorrect, the code bellow would not work.

  • Please get the code working on a desktop platform first before trying it on Windows Mobile 5. If it doesn't work on desktop, it won't work on Pocket PC. (Don't forget to load an ECC plugin before trying this on the mobile platform.)

  • The code below needs to reference Rebex.Common and Rebex.Networking assemblies.

This will load the private key and filetosign, create a signature using the CreateEncodedSignature helper method (see below) and save it into a file:

' load private key
Dim key = New SshPrivateKey("priv.pem", "secretpassword")

' load content to sign
Dim content As Byte() = File.ReadAllBytes("filetosign")

' create encoded signature
Dim signature As Byte() = CreateEncodedSignature(key, content)

' save the signature
File.WriteAllBytes("sign.sha", signature)

The CreateEncodedSignature helper method that creates a signature and converts it into desired format looks like this:

Public Shared Function CreateEncodedSignature(key As SshPrivateKey, message As Byte()) As Byte()
    Dim hashAlg As SignatureHashAlgorithm
    Select Case key.KeyAlgorithm
        Case SshHostKeyAlgorithm.ECDsaNistP256
            hashAlg = SignatureHashAlgorithm.SHA256
            Exit Select
        Case SshHostKeyAlgorithm.ECDsaNistP384
            hashAlg = SignatureHashAlgorithm.SHA384
            Exit Select
        Case SshHostKeyAlgorithm.ECDsaNistP521
            hashAlg = SignatureHashAlgorithm.SHA512
            Exit Select
        Case Else
            Throw New InvalidOperationException("Key algorithm not supported yet.")
    End Select

    ' sign the message
    Dim signature As Byte() = key.CreateSignature(message, hashAlg)

    ' convert the signature into a format used by "openssl dgst" command

    Dim offset As Integer = 30
    Dim length1 As Integer = signature(offset)
    Dim offset1 As Integer = offset + 1
    offset = offset + 1 + length1 + 3
    Dim length2 As Integer = signature(offset)
    Dim offset2 As Integer = offset + 1

    Dim result = New MemoryStream()

    ' ASN.1 sequence and length
    result.WriteByte(&H30)
    Dim length As Integer = length1 + length2 + 6
    If length < &H80 Then
        result.WriteByte(CByte(length))
    Else
        result.WriteByte(&H81)
        result.WriteByte(CByte(length))
    End If

    ' ASN.1 integer, length and content
    result.WriteByte(&H2)
    result.WriteByte(CByte(length1))
    result.Write(signature, offset1, length1)

    ' ASN.1 integer, length and content
    result.WriteByte(&H2)
    result.WriteByte(CByte(length2))
    result.Write(signature, offset2, length2)

    Return result.ToArray()
End Function

Viewing all articles
Browse latest Browse all 3862

Trending Articles