簡単な説明:
PHP で RSA キーペアを生成し、それを VB.NET で使用してファイル/文字列を暗号化/復号化できるようにする必要があります。
ファイルの暗号化/復号化 VB.NET: http://jandrozd.eu/RSAFileEncryption.zip
これに基づく: http://www.tma.dk/rsa/
PHPSecLib で生成されたキーではなく、.NET で生成されたキーで動作します。
詳細:
ある会社の社内情報システムを作成しています。これは、VB.NET デスクトップ クライアントと PHP サーバーに基づいています。お客様のセキュリティ要件により、ファイルまたは文字列を保存する際に RSA 暗号化を使用する必要があります。また、転送中/転送前に暗号化する必要があります。
RSAキーペアを生成するコードをPHPで探していました。それをうまく生成するphpseclibを見つけました。サーバーでこれを使用します:
$rsa = new Crypt_RSA();
$rsa->setEncryptionMode(CRYPT_RSA_PUBLIC_FORMAT_PKCS1);
$rsa->setPrivateKeyFormat(CRYPT_RSA_PRIVATE_FORMAT_XML);
$rsa->setPublicKeyFormat(CRYPT_RSA_PUBLIC_FORMAT_XML);
//define('CRYPT_RSA_EXPONENT', 65537);
//define('CRYPT_RSA_SMALLEST_PRIME', 64); // makes it so multi-prime RSA is used
extract($rsa->createKey(512)); // == $rsa->createKey(1024) where 1024 is the key size
また、キーが生成されたテキスト ファイルも保存します。問題は、VB.NET でこれらのキーを使用して暗号化および復号化しようとしたときに発生します。phpseclib で生成されたキーを使用した暗号化は VB.NET でうまく機能しているようですが、VB.NET でファイルを復号化できません。
Public Sub EncryptFile(ByVal strFilePath As String, ByVal strNewPath As String, ByVal strPublicKey As String)
Try
If File.Exists(strFilePath) Then
Dim bts() As Byte = My.Computer.FileSystem.ReadAllBytes(strFilePath)
Dim EncryptedMessage As RSAResult = RSA.Encrypt(bts, strPublicKey)
My.Computer.FileSystem.WriteAllBytes(strNewPath, EncryptedMessage.AsBytes, False)
If EnableMessageBoxes Then MsgBox("Encryption complete", MsgBoxStyle.Information)
Else
If EnableMessageBoxes Then MsgBox("File to encrypt does not exists", MsgBoxStyle.Exclamation)
End If
Catch ex As Exception
If EnableMessageBoxes Then MsgBox("Encryption error: " & ex.Message, MsgBoxStyle.Critical)
End Try
End Sub
Public Sub DecryptFile(ByVal strFilePath As String, ByVal strNewPath As String, ByVal strPrivateKey As String)
Try
If File.Exists(strFilePath) Then
Dim bts() As Byte = My.Computer.FileSystem.ReadAllBytes(strFilePath)
Dim DecryptedMessage As RSAResult = RSA.Decrypt(bts, strPrivateKey)
My.Computer.FileSystem.WriteAllBytes(strNewPath, DecryptedMessage.AsBytes, False)
If EnableMessageBoxes Then MsgBox("Decryption complete", MsgBoxStyle.Information)
Else
If EnableMessageBoxes Then MsgBox("File to encrypt does not exists", MsgBoxStyle.Exclamation)
End If
Catch ex As Exception
If EnableMessageBoxes Then MsgBox("Decryption error: " & ex.Message, MsgBoxStyle.Critical)
End Try
End Sub
VB.NET RSA クラス
Imports System.Security.Cryptography
Imports System.Text
Public Class RSA
Public Shared Function Encrypt(ByVal Data As String, ByVal Publickey As String) As RSAResult
Try
Dim ByteConverter As New UnicodeEncoding()
Return Encrypt(ByteConverter.GetBytes(Data), Publickey)
Catch ex As Exception
Throw New Exception("Encrypt(String): " & ex.Message, ex)
End Try
End Function
Public Shared Function Encrypt(ByVal Data() As Byte, ByVal Publickey As String) As RSAResult
Try
Dim RSA As System.Security.Cryptography.RSACryptoServiceProvider = New System.Security.Cryptography.RSACryptoServiceProvider()
RSA.FromXmlString(Publickey)
Return New RSAResult(RSAEncrypt(Data, RSA.ExportParameters(False), False))
Catch ex As Exception
Throw New Exception("Encrypt(Bytes): " & ex.Message, ex)
End Try
End Function
Public Shared Function Decrypt(ByVal Data() As Byte, ByVal Privatekey As String) As RSAResult
Try
Dim RSA As System.Security.Cryptography.RSACryptoServiceProvider = New System.Security.Cryptography.RSACryptoServiceProvider()
RSA.FromXmlString(Privatekey)
Dim Result As New RSAResult(RSADecrypt(Data, RSA.ExportParameters(True), False))
Return Result
Catch ex As Exception
Throw New Exception("Decrypt(): " & ex.Message, ex)
End Try
End Function
Private Shared Function RSAEncrypt(ByVal DataToEncrypt() As Byte, ByVal RSAKeyInfo As RSAParameters, ByVal DoOAEPPadding As Boolean) As Byte()
Try
Dim encryptedData() As Byte
Using RSA As New RSACryptoServiceProvider
RSA.ImportParameters(RSAKeyInfo)
encryptedData = RSA.Encrypt(DataToEncrypt, DoOAEPPadding)
End Using
Return encryptedData
Catch e As CryptographicException
Throw New Exception("RSAEncrypt(): " & e.Message, e)
End Try
End Function
Private Shared Function RSADecrypt(ByVal DataToDecrypt() As Byte, ByVal RSAKeyInfo As RSAParameters, ByVal DoOAEPPadding As Boolean) As Byte()
Try
Dim decryptedData() As Byte
Using RSA As New RSACryptoServiceProvider
RSA.ImportParameters(RSAKeyInfo)
decryptedData = RSA.Decrypt(DataToDecrypt, DoOAEPPadding)
End Using
Return decryptedData
Catch e As CryptographicException
Throw New Exception("RSADecrypt(): " & e.Message, e)
End Try
End Function
RSAResult クラス:
Imports System.Text
Public Class RSAResult
Private _Data() As Byte
Public Sub New(ByVal Data() As Byte)
_Data = Data
End Sub
Public ReadOnly Property AsBytes() As Byte()
Get
Return _Data
End Get
End Property
Public ReadOnly Property AsString() As String
Get
Dim ByteConverter As New UnicodeEncoding()
Return ByteConverter.GetString(_Data)
End Get
End Property
Public ReadOnly Property AsBase64String() As String
Get
Return Convert.ToBase64String(_Data)
End Get
End Property
End Class
生成されたキーの例:
プライベート:
<RSAKeyValue>
<Modulus>AN3mGF2XtuTBC7jaBhPrVNYyheYX4HuCkhRpRXOCcKVOseahQBokzn555hIW0fK3kamVLOkSvSF6hP8rt1PC/Qs=</Modulus>
<Exponent>AQAB</Exponent>
<P>APeyh3iQRVNleEHNEx8cVCxYMIA7pCiSdYDGWJwf9meZ</P>
<Q>AOVWMMpSkGlHtHe8aIgu9xw1lUiJ6VZIxVckPyj8oOBD</Q>
<DP>AM20C+FKHuilSfuLbafWhOjWzGCSJ0AycTbigdAWkzFx</DP>
<DQ>AMCTd7TtT8aYJ7rDwyNYDLjrZcfbxsxlnxBlp4PLX2vx</DQ>
<InverseQ>AJ2/aZW5UR/pkQeA6BMKdhqqTWa5mjzMlnOga6zPlRdN</InverseQ>
<D>AShwPBzMkYkIXKCWo4f4211MIZVCUKKvzHd4K1Ak8lfiTH4oxB8fgq4aa2QT5ufDwedlKGJLnuY6Kv9SpkMOIQ==</D>
</RSAKeyValue>
公衆:
<RSAKeyValue>
<Modulus>AN3mGF2XtuTBC7jaBhPrVNYyheYX4HuCkhRpRXOCcKVOseahQBokzn555hIW0fK3kamVLOkSvSF6hP8rt1PC/Qs=</Modulus>
<Exponent>AQAB</Exponent>
</RSAKeyValue>