From cb649c88ede2c7506b868c8828a23f69e383adbb Mon Sep 17 00:00:00 2001 From: "Namhyeon, Go" Date: Sat, 5 Jul 2025 13:24:10 +0900 Subject: [PATCH] Update SEED algorithm --- .../WelsonJS.Cryptography.Test/Program.vb | 14 +--- .../WelsonJS.Cryptography/SeedEcbTransform.vb | 77 ++++++++++++++++--- 2 files changed, 72 insertions(+), 19 deletions(-) diff --git a/WelsonJS.Toolkit/WelsonJS.Cryptography.Test/Program.vb b/WelsonJS.Toolkit/WelsonJS.Cryptography.Test/Program.vb index 5b155f9..ca81ac7 100644 --- a/WelsonJS.Toolkit/WelsonJS.Cryptography.Test/Program.vb +++ b/WelsonJS.Toolkit/WelsonJS.Cryptography.Test/Program.vb @@ -12,8 +12,8 @@ Module Program Console.WriteLine("Start SEED encryption and decryption test") Dim cipher As New WelsonJS.Cryptography.SeedAlgorithm() - cipher.Key = {&H2B, &H7E, &H15, &H16, &H28, &HAE, &HD2, &HA6, &HAB, &HF7, &H15, &H88, &H9, &HCF, &H4F, &H3C} - cipher.IV = {&H26, &H8D, &H66, &HA7, &H35, &HA8, &H1A, &H81, &H6F, &HBA, &HD9, &HFA, &H36, &H16, &H25, &H1} + cipher.Key = {&H88, &HE3, &H4F, &H8F, &H8, &H17, &H79, &HF1, &HE9, &HF3, &H94, &H37, &HA, &HD4, &H5, &H89} + ' cipher.IV = {&H26, &H8D, &H66, &HA7, &H35, &HA8, &H1A, &H81, &H6F, &HBA, &HD9, &HFA, &H36, &H16, &H25, &H1} cipher.Mode = CipherMode.ECB cipher.Padding = PaddingMode.PKCS7 @@ -21,7 +21,7 @@ Module Program End Sub Public Sub RunTest(cipher As SymmetricAlgorithm) - Dim inputBytes As Byte() = {&H0, &H1, &H2, &H3, &H4, &H5, &H6, &H7, &H8, &H9, &HA, &HB, &HC, &HD, &HE, &HF, &H0, &H1} + Dim inputBytes As Byte() = {&H0, &H0, &H0, &H0, &H0, &H0, &H0, &H0, &H0, &H0, &H0, &H0, &H0, &H0, &H0, &HFE} Console.WriteLine("Original bytes (HEX):") PrintHex(inputBytes) @@ -38,13 +38,7 @@ Module Program End Sub Private Function ApplyTransform(transformer As ICryptoTransform, input As Byte()) As Byte() - Using ms As New MemoryStream() - Using cs As New CryptoStream(ms, transformer, CryptoStreamMode.Write) - cs.Write(input, 0, input.Length) - cs.FlushFinalBlock() - Return ms.ToArray() - End Using - End Using + Return transformer.TransformFinalBlock(input, 0, input.Length) End Function Private Sub PrintHex(data As Byte()) diff --git a/WelsonJS.Toolkit/WelsonJS.Cryptography/SeedEcbTransform.vb b/WelsonJS.Toolkit/WelsonJS.Cryptography/SeedEcbTransform.vb index d4ce3c3..77ba113 100644 --- a/WelsonJS.Toolkit/WelsonJS.Cryptography/SeedEcbTransform.vb +++ b/WelsonJS.Toolkit/WelsonJS.Cryptography/SeedEcbTransform.vb @@ -8,6 +8,7 @@ Imports System.Security.Cryptography Public Class SeedEcbTransform Implements ICryptoTransform + Private ReadOnly rnd As New Random() Private ReadOnly seedCore As SeedCore Private ReadOnly encrypt As Boolean Private ReadOnly paddingMode As PaddingMode @@ -76,13 +77,23 @@ Public Class SeedEcbTransform If (inputCount Mod blockSize) <> 0 Then Throw New CryptographicException("Input data is not a multiple of block size and PaddingMode is None.") End If + ' None 패딩은 추가 블록 없음 paddedLength = inputCount Case PaddingMode.Zeros + ' Zeros 패딩은 추가 블록 필요 없음 paddedLength = ((inputCount + blockSize - 1) \ blockSize) * blockSize - Case PaddingMode.PKCS7 - paddedLength = ((inputCount + blockSize - 1) \ blockSize) * blockSize + Case PaddingMode.PKCS7, PaddingMode.ANSIX923, PaddingMode.ISO10126 + ' PKCS7. ANSIX923, ISO10126 패딩은 입력이 블록 배수면 +1 블록 추가 + ' (설명) 블록암호에서 블록 길이와 같은 길이의 원문을 넣으면, 암호화문 길이가 원문 길이의 2배가 되는 원인은 여기에 기인한다. + Dim fullBlocks As Integer = inputCount \ blockSize + Dim remainder As Integer = inputCount Mod blockSize + If remainder = 0 Then + paddedLength = (fullBlocks + 1) * blockSize ' 추가 블록 붙임 + Else + paddedLength = (fullBlocks + 1) * blockSize + End If Case Else Throw New NotSupportedException("Unsupported padding mode: " & paddingMode.ToString()) @@ -91,20 +102,32 @@ Public Class SeedEcbTransform buffer = New Byte(paddedLength - 1) {} Array.Copy(input, inputOffset, buffer, 0, inputCount) - If paddingMode = PaddingMode.Zeros Then - ' All filling to zero - ElseIf paddingMode = PaddingMode.PKCS7 Then + If paddingMode = PaddingMode.PKCS7 Then Dim padValue As Byte = CByte(paddedLength - inputCount) For i As Integer = inputCount To paddedLength - 1 buffer(i) = padValue Next + + ElseIf paddingMode = PaddingMode.ANSIX923 Then + Dim padValue As Byte = CByte(paddedLength - inputCount) + For i As Integer = inputCount To paddedLength - 2 + buffer(i) = 0 + Next + buffer(paddedLength - 1) = padValue + + ElseIf paddingMode = PaddingMode.ISO10126 Then + Dim padValue As Byte = CByte(paddedLength - inputCount) + For i As Integer = inputCount To paddedLength - 2 + buffer(i) = CByte(rnd.Next(0, 256)) + Next + buffer(paddedLength - 1) = padValue End If TransformBlock(buffer, 0, paddedLength, buffer, 0) Return buffer Else - ' Decrpytion + ' Decryption If (inputCount Mod blockSize) <> 0 Then Throw New CryptographicException("Encrypted data is not a multiple of block size.") End If @@ -132,13 +155,49 @@ Public Class SeedEcbTransform End If For i As Integer = buffer.Length - padValue To buffer.Length - 1 If buffer(i) <> padValue Then - Throw New CryptographicException("Invalid PKCS7 padding.") + Throw New CryptographicException("Invalid PKCS7 padding value.") End If Next - Dim result(buffer.Length - padValue - 1) As Byte - Array.Copy(buffer, 0, result, 0, result.Length) + Dim unpaddedLength As Integer = buffer.Length - padValue + If unpaddedLength < 0 Then + Throw New CryptographicException("Invalid unpadded length.") + End If + Dim result(unpaddedLength - 1) As Byte + Array.Copy(buffer, 0, result, 0, unpaddedLength) Return result + Case PaddingMode.ANSIX923 + Dim padValue As Integer = buffer(buffer.Length - 1) + If padValue <= 0 OrElse padValue > blockSize Then + Throw New CryptographicException("Invalid ANSIX923 padding.") + End If + For i As Integer = buffer.Length - padValue To buffer.Length - 2 + If buffer(i) <> 0 Then + Throw New CryptographicException("Invalid ANSIX923 padding value.") + End If + Next + Dim unpaddedLengthAnsix As Integer = buffer.Length - padValue + If unpaddedLengthAnsix < 0 Then + Throw New CryptographicException("Invalid unpadded length.") + End If + Dim resultAnsix(unpaddedLengthAnsix - 1) As Byte + Array.Copy(buffer, 0, resultAnsix, 0, unpaddedLengthAnsix) + Return resultAnsix + + Case PaddingMode.ISO10126 + Dim padValue As Integer = buffer(buffer.Length - 1) + If padValue <= 0 OrElse padValue > blockSize Then + Throw New CryptographicException("Invalid ISO10126 padding.") + End If + ' Check the last byte (length) + Dim unpaddedLengthIso As Integer = buffer.Length - padValue + If unpaddedLengthIso < 0 Then + Throw New CryptographicException("Invalid unpadded length.") + End If + Dim resultIso(unpaddedLengthIso - 1) As Byte + Array.Copy(buffer, 0, resultIso, 0, unpaddedLengthIso) + Return resultIso + Case Else Throw New NotSupportedException("Unsupported padding mode: " & paddingMode.ToString()) End Select