Golang RSA Private Key Parsing: PKCS#1 Format
func ParsePKCS1PrivateKey(der []byte) (*rsa.PrivateKey, error) {
var priv pkcs1PrivateKey
rest, err := asn1.Unmarshal(der, &priv)
if len(rest) > 0 {
return nil, asn1.SyntaxError{Msg: 'trailing data'}
}
if err != nil {
if _, err := asn1.Unmarshal(der, &ecPrivateKey{}); err == nil {
return nil, errors.New('x509: failed to parse private key (use ParseECPrivateKey instead for this key format)')
}
if _, err := asn1.Unmarshal(der, &pkcs8{}); err == nil {
return nil, errors.New('x509: failed to parse private key (use ParsePKCS8PrivateKey instead for this key format)')
}
return nil, err
}
if priv.Version > 1 {
return nil, errors.New('x509: unsupported private key version')
}
if priv.N.Sign() <= 0 || priv.D.Sign() <= 0 || priv.P.Sign() <= 0 || priv.Q.Sign() <= 0 {
return nil, errors.New('x509: private key contains zero or negative value')
}
key := new(rsa.PrivateKey)
key.PublicKey = rsa.PublicKey{
E: priv.E,
N: priv.N,
}
key.D = priv.D
key.Primes = make([]*big.Int, 2+len(priv.AdditionalPrimes))
key.Primes[0] = priv.P
key.Primes[1] = priv.Q
for i, a := range priv.AdditionalPrimes {
if a.Prime.Sign() <= 0 {
return nil, errors.New('x509: private key contains zero or negative prime')
}
key.Primes[i+2] = a.Prime
// We ignore the other two values because rsa will calculate
// them as needed.
}
err = key.Validate()
if err != nil {
return nil, err
}
key.Precompute()
return key, nil
}
func genPriKey(privateKey []byte, privateKeyType Type) (*rsa.PrivateKey, error) {
var priKey *rsa.PrivateKey
var err error
switch privateKeyType {
case PKCS1:
{
priKey, err = x509.ParsePKCS1PrivateKey([]byte(privateKey))
if err != nil {
return nil, err
}
}
case PKCS8:
{
prkI, err := x509.ParsePKCS8PrivateKey([]byte(privateKey))
if err != nil {
return nil, err
}
priKey = prkI.(*rsa.PrivateKey)
}
default:
{
return nil, errors.New('unsupport private key type')
}
}
return priKey, nil
}
func NewRsa(privateKey, publicKey []byte, privateKeyType Type) (Cipher, error) {
priKey, err := genPriKey(privateKey, privateKeyType)
if err != nil {
return nil, err
}
pubKey, err := genPubKey(publicKey)
if err != nil {
return nil, err
}
return &pkcsClient{privateKey: priKey, publicKey: pubKey}, nil
}
{ //处理获取aes key请求
if r.Header.Get('Request-Aes-Key-Id') != '' {
//conn := a.pool.Get()
//defer conn.Close()
cr, err := NewRsa(base64Decode(priKey), base64Decode(pubKey), PKCS1) //按理来说不能多次使用
if err != nil {
rw.WriteHeader(500)
rw.Write([]byte('RSA密钥错误'))
return
}
r.ParseForm()
keybase64 := r.Form.Get('aesKey')
//body, _ := ioutil.ReadAll(r.Body)
keyDecrypted, err := cr.Decrypt(base64Decode(keybase64))
if err != nil {
rw.WriteHeader(500)
rw.Write([]byte('AES密钥解密失败'))
return
}
id := uuid.NewUUID()
if err := a.client.Insert(&dao.AesId{Key: string('gateway:clientAESKey:' + id), Value: string(keyDecrypted), Time: time.Now().Unix()}); err != nil {
log.WithoutContext().Errorln(err)
}
//conn.Do('SET', 'gateway:clientAESKey:'+id, keyDecrypted, 'EX', 3600*24*30)
rw.Header().Set('Content-Type', 'application/json')
rw.Write([]byte(jsonutil.MarshalToString2(RespBody{
Code: 200,
Data: id,
})))
return
}
}
Java Implementation:
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import javax.crypto.Cipher;
public class RSAUtils {
public static PrivateKey parsePKCS1PrivateKey(byte[] der) throws NoSuchAlgorithmException, InvalidKeySpecException {
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(der);
KeyFactory keyFactory = KeyFactory.getInstance('RSA');
return keyFactory.generatePrivate(keySpec);
}
public static PublicKey parsePublicKey(byte[] der) throws NoSuchAlgorithmException, InvalidKeySpecException {
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(der);
KeyFactory keyFactory = KeyFactory.getInstance('RSA');
return keyFactory.generatePublic(keySpec);
}
public static byte[] decryptWithPrivateKey(PrivateKey privateKey, byte[] encryptedData) throws Exception {
Cipher cipher = Cipher.getInstance('RSA');
cipher.init(Cipher.DECRYPT_MODE, privateKey);
return cipher.doFinal(encryptedData);
}
}
public class AesKeyHandler {
private PrivateKey privateKey;
private PublicKey publicKey;
public AesKeyHandler(byte[] privateKeyBytes, byte[] publicKeyBytes) throws NoSuchAlgorithmException, InvalidKeySpecException {
this.privateKey = RSAUtils.parsePKCS1PrivateKey(privateKeyBytes);
this.publicKey = RSAUtils.parsePublicKey(publicKeyBytes);
}
public byte[] decryptAesKey(byte[] encryptedAesKey) throws Exception {
return RSAUtils.decryptWithPrivateKey(privateKey, encryptedAesKey);
}
}
// Usage
byte[] privateKeyBytes = Base64.getDecoder().decode(privateKey);
byte[] publicKeyBytes = Base64.getDecoder().decode(publicKey);
AesKeyHandler aesKeyHandler = new AesKeyHandler(privateKeyBytes, publicKeyBytes);
byte[] decryptedAesKey = aesKeyHandler.decryptAesKey(encryptedAesKey);
原文地址: https://www.cveoy.top/t/topic/pg9o 著作权归作者所有。请勿转载和采集!