Golang使用golang.org/x/crypto/openpgp进行加密和解密的问题求助

Golang使用golang.org/x/crypto/openpgp进行加密和解密的问题求助 你好,

我一直在尝试解密和加密与API交互时接收和发送的ASCII armor格式的PGP消息。

我编写了一个用于解密消息的函数和另一个用于加密消息的函数。解密函数工作正常,我可以解密来自API的消息。但我的加密函数似乎有问题,因为无论是API还是我自己的解密函数都无法解密由我的加密函数加密的消息。尝试解密由我的加密函数加密的消息总是导致以下错误:“Error reading message: openpgp: unsupported feature: unknown SymmetricallyEncrypted version”

以下是存在问题的加密函数:

func encryptMessage(publicKey, privateKey, privateKeyPassword, message string) (string, error) {

	pubEl, err := openpgp.ReadArmoredKeyRing(strings.NewReader(publicKey))
	if err != nil {
		return "", fmt.Errorf("Error Reading Public Keyring: %v", err)
	}

	privEl, err := openpgp.ReadArmoredKeyRing(strings.NewReader(privateKey))
	if err != nil {
		return "", fmt.Errorf("Error Reading Private Keyring: %v", err)
	}

	privateEntity := privEl[0]
	err = privateEntity.PrivateKey.Decrypt([]byte(privateKeyPassword))
	if err != nil {
		return "", fmt.Errorf("Error decrypting PrivateKey: %v", err)
	}
	for _, subkey := range privateEntity.Subkeys {
		err = subkey.PrivateKey.Decrypt([]byte(privateKeyPassword))
		if err != nil {
			return "", fmt.Errorf("Error decrypting PrivateKey: %v", err)
		}
	}

	buf := new(bytes.Buffer)

	encoderWriter, err := armor.Encode(buf, "PGP Message", make(map[string]string))
	if err != nil {
		return "", fmt.Errorf("Error creating OpenPGP armor: %v", err)
	}

	encryptorWriter, err := openpgp.Encrypt(encoderWriter, pubEl, nil, nil, nil)
	if err != nil {
		return "", fmt.Errorf("Error Encrypting Message: %v", err)
	}

	messageReader := bytes.NewReader([]byte(message))
	_, err = io.Copy(encoderWriter, messageReader)
	if err != nil {
		return "", fmt.Errorf("Error writing data to encoder: %v", err)
	}

	encryptorWriter.Close()
	encoderWriter.Close()

	return string(buf.Bytes()), nil
}

我已经在Go Play Ground上传了一个示例:https://play.golang.org/p/JhhZ4xWWYvn

任何帮助都将不胜感激。


更多关于Golang使用golang.org/x/crypto/openpgp进行加密和解密的问题求助的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于Golang使用golang.org/x/crypto/openpgp进行加密和解密的问题求助的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


问题出在加密函数的写入流程上。您错误地将数据写入了encoderWriter而不是encryptorWriter,这导致加密后的数据没有正确通过ASCII armor编码器。

以下是修复后的加密函数:

func encryptMessage(publicKey, privateKey, privateKeyPassword, message string) (string, error) {
    pubEl, err := openpgp.ReadArmoredKeyRing(strings.NewReader(publicKey))
    if err != nil {
        return "", fmt.Errorf("Error Reading Public Keyring: %v", err)
    }

    privEl, err := openpgp.ReadArmoredKeyRing(strings.NewReader(privateKey))
    if err != nil {
        return "", fmt.Errorf("Error Reading Private Keyring: %v", err)
    }

    privateEntity := privEl[0]
    err = privateEntity.PrivateKey.Decrypt([]byte(privateKeyPassword))
    if err != nil {
        return "", fmt.Errorf("Error decrypting PrivateKey: %v", err)
    }
    for _, subkey := range privateEntity.Subkeys {
        err = subkey.PrivateKey.Decrypt([]byte(privateKeyPassword))
        if err != nil {
            return "", fmt.Errorf("Error decrypting PrivateKey: %v", err)
        }
    }

    buf := new(bytes.Buffer)

    encoderWriter, err := armor.Encode(buf, "PGP Message", make(map[string]string))
    if err != nil {
        return "", fmt.Errorf("Error creating OpenPGP armor: %v", err)
    }

    encryptorWriter, err := openpgp.Encrypt(encoderWriter, pubEl, nil, nil, nil)
    if err != nil {
        return "", fmt.Errorf("Error Encrypting Message: %v", err)
    }

    messageReader := bytes.NewReader([]byte(message))
    _, err = io.Copy(encryptorWriter, messageReader)
    if err != nil {
        return "", fmt.Errorf("Error writing data to encryptor: %v", err)
    }

    encryptorWriter.Close()
    encoderWriter.Close()

    return buf.String(), nil
}

关键修改:

  1. io.Copy(encoderWriter, messageReader)改为io.Copy(encryptorWriter, messageReader)
  2. 确保数据先通过加密器,再通过ASCII armor编码器

如果您需要同时签名和加密,可以使用以下版本:

func encryptAndSignMessage(publicKey, privateKey, privateKeyPassword, message string) (string, error) {
    pubEl, err := openpgp.ReadArmoredKeyRing(strings.NewReader(publicKey))
    if err != nil {
        return "", fmt.Errorf("Error Reading Public Keyring: %v", err)
    }

    privEl, err := openpgp.ReadArmoredKeyRing(strings.NewReader(privateKey))
    if err != nil {
        return "", fmt.Errorf("Error Reading Private Keyring: %v", err)
    }

    privateEntity := privEl[0]
    err = privateEntity.PrivateKey.Decrypt([]byte(privateKeyPassword))
    if err != nil {
        return "", fmt.Errorf("Error decrypting PrivateKey: %v", err)
    }
    for _, subkey := range privateEntity.Subkeys {
        err = subkey.PrivateKey.Decrypt([]byte(privateKeyPassword))
        if err != nil {
            return "", fmt.Errorf("Error decrypting PrivateKey: %v", err)
        }
    }

    buf := new(bytes.Buffer)

    encoderWriter, err := armor.Encode(buf, "PGP Message", make(map[string]string))
    if err != nil {
        return "", fmt.Errorf("Error creating OpenPGP armor: %v", err)
    }

    encryptorWriter, err := openpgp.Encrypt(encoderWriter, pubEl, privateEntity, nil, nil)
    if err != nil {
        return "", fmt.Errorf("Error Encrypting Message: %v", err)
    }

    messageReader := bytes.NewReader([]byte(message))
    _, err = io.Copy(encryptorWriter, messageReader)
    if err != nil {
        return "", fmt.Errorf("Error writing data to encryptor: %v", err)
    }

    encryptorWriter.Close()
    encoderWriter.Close()

    return buf.String(), nil
}

这个修改后的版本将确保数据正确经过加密管道,API和您的解密函数应该能够正常解密。

回到顶部