2012-04-24 107 views
1

我主要发布此为需要它的任何人,因为似乎有很大的互联网资源缺乏这个。我确实发现的样品看起来似乎蹒跚在一起,从来没有为我工作过。如果你看到或发现这个班有什么问题,我很想知道。请注意,这个类稍微修改了我的特定实现,但应该在Bouncy Castle .Net源代码的1.7版本上正常工作。Bouncy城​​堡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)所取代。