2012-04-24 4 views
1

Я в основном размещаю это для всех, кто нуждается в нем, поскольку для этого, похоже, существует большая нехватка ресурсов в Интернете. Образцы, которые я нашел, казались сколоченными в лучшем случае и никогда не работали для меня. Если вы увидите или найдете что-то не так с этим классом, я бы с удовольствием узнал. Обратите внимание, что этот класс немного изменен для моей конкретной реализации, но должен отлично работать с версией 1.7 исходного кода Bouncy Castle .Net.Bouncy Castle OpenPGP с VB.Net

Imports System.IO 
Imports Org.BouncyCastle.Bcpg.OpenPgp 

Public Class PgpDecrypt 
    Private _mPublicKeyPath As String = "C:\MyPgpKeys\MyKey - Public.asc" 
    Private _mPrivateKeyPath As String = "C:\MyPgpKeys\MyKey - Private.asc" 
    Private _mPassPhrase As String = "<passwoid>" 

    Public Function Decrypt(ByVal srcPath As String, ByVal dstPath As String) As Boolean 
     Dim stEnc As Stream = PgpUtilities.GetDecoderStream(File.OpenRead(srcPath)) 
     Dim pof As New PgpObjectFactory(stEnc) 
     Dim pked As PgpPublicKeyEncryptedData = Nothing 

     Dim keyPrivate As PgpPrivateKey = Nothing 
     For Each pked In GetEncryptedDataList(pof).GetEncryptedDataObjects 
      keyPrivate = ReadPrivateKey(pked.KeyId) 
      If Not keyPrivate Is Nothing Then Exit For 
     Next 
     If keyPrivate Is Nothing Then Return False 

     Dim stDec As Stream = pked.GetDataStream(keyPrivate) 
     pof = New PgpObjectFactory(stDec) 
     Dim o As PgpObject = pof.NextPgpObject 
     If TypeOf o Is PgpCompressedData Then 
      pof = New PgpObjectFactory(DirectCast(o, PgpCompressedData).GetDataStream) 
      o = pof.NextPgpObject 
     End If 
     While Not TypeOf o Is PgpLiteralData 
      o = pof.NextPgpObject 
      If o Is Nothing Then Return False 
     End While 
     Dim ld As PgpLiteralData = DirectCast(o, PgpLiteralData) 
     Dim stOut As Stream = File.Create(dstPath) 
     Dim stUnc As Stream = ld.GetInputStream 
     Org.BouncyCastle.OpenPgp.Utilities.IO.Streams.PipeAll(stUnc, stOut) 
     stOut.Close() 

     Return True 
    End Function 

    Private Function GetEncryptedDataList(ByVal pof As PgpObjectFactory) As PgpEncryptedDataList 
     Dim o As PgpObject = Nothing 
     While Not TypeOf o Is PgpEncryptedDataList 
      o = pof.NextPgpObject 
      If o Is Nothing Then Return Nothing 
     End While 
     Return DirectCast(o, PgpEncryptedDataList) 
    End Function 

    Private Function ReadPublicKey(Optional ByVal useEmbedded As Boolean = False) As PgpPublicKey 
     If useEmbedded Then 
      Using st As Stream = Reflection.Assembly.GetExecutingAssembly.GetManifestResourceStream(GetAssemblyName() & ".MyKey - Public.asc") 
       Dim bundle As PgpSecretKeyRingBundle = New PgpSecretKeyRingBundle(PgpUtilities.GetDecoderStream(st)) 
       For Each ring As PgpPublicKeyRing In bundle.GetKeyRings 
        For Each key As PgpPublicKey In ring.GetPublicKeys 
         If key.IsEncryptionKey Then Return key 
        Next 
       Next 
      End Using 
     Else 
      Using st As Stream = File.OpenRead(_mPublicKeyPath) 
       Dim bundle As PgpPublicKeyRingBundle = New PgpPublicKeyRingBundle(PgpUtilities.GetDecoderStream(st)) 
       For Each ring As PgpPublicKeyRing In bundle.GetKeyRings 
        For Each key As PgpPublicKey In ring.GetPublicKeys 
         If key.IsEncryptionKey Then Return key 
        Next 
       Next 
      End Using 
     End If 

     Return Nothing 
    End Function 

    Private Function ReadSecretKey(Optional ByVal useEmbedded As Boolean = False) As PgpSecretKey 
     If useEmbedded Then 
      Using st As Stream = Reflection.Assembly.GetExecutingAssembly.GetManifestResourceStream(GetAssemblyName() & ".MyKey - Private.asc") 
       Dim bundle As PgpSecretKeyRingBundle = New PgpSecretKeyRingBundle(PgpUtilities.GetDecoderStream(st)) 
       For Each ring As PgpSecretKeyRing In bundle.GetKeyRings 
        For Each key As PgpSecretKey In ring.GetSecretKeys 
         If key.IsSigningKey Then Return key 
        Next 
       Next 
      End Using 
     Else 
      Using st As Stream = File.OpenRead(_mPrivateKeyPath) 
       Dim bundle As PgpSecretKeyRingBundle = New PgpSecretKeyRingBundle(PgpUtilities.GetDecoderStream(st)) 
       For Each ring As PgpSecretKeyRing In bundle.GetKeyRings 
        For Each key As PgpSecretKey In ring.GetSecretKeys 
         If key.IsSigningKey Then Return key 
        Next 
       Next 
      End Using 
     End If 

     Return Nothing 
    End Function 

    Private Function ReadPrivateKey(ByVal keyId As Long, Optional ByVal useEmbedded As Boolean = False) As PgpPrivateKey 
     If useEmbedded Then 
      Using st As Stream = Reflection.Assembly.GetExecutingAssembly.GetManifestResourceStream(GetAssemblyName() & ".MyKey - Private.asc") 
       Dim bundle As PgpSecretKeyRingBundle = New PgpSecretKeyRingBundle(PgpUtilities.GetDecoderStream(st)) 
       Dim key As PgpSecretKey = bundle.GetSecretKey(keyId) 
       If key Is Nothing Then Return Nothing 
       Return key.ExtractPrivateKey(_mPassPhrase) 
      End Using 
     Else 
      Using st As Stream = File.OpenRead(_mPrivateKeyPath) 
       Dim bundle As PgpSecretKeyRingBundle = New PgpSecretKeyRingBundle(PgpUtilities.GetDecoderStream(st)) 
       Dim key As PgpSecretKey = bundle.GetSecretKey(keyId) 
       If key Is Nothing Then Return Nothing 
       Return key.ExtractPrivateKey(_mPassPhrase) 
      End Using 
     End If 
    End Function 

    Private Function GetAssemblyName() As String 
     Dim names() As String = Reflection.Assembly.GetExecutingAssembly.GetManifestResourceNames 
     If names.Length > 0 Then 
      Return names(0).Split(".").First 
     Else 
      Return String.Empty 
     End If 
    End Function 
End Class 

ответ

1

Удивительный! Большое спасибо за публикацию этого - он работал в значительной степени из коробки. Одно изменение было Org.BouncyCastle.OpenPgp.Utilities.IO.Streams.PipeAll(stUnc, stOut) необходимо было заменить на Org.BouncyCastle.Utilities.IO.Streams.PipeAll(stUnc, stOut).

Смежные вопросы