You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
126 lines
3.9 KiB
126 lines
3.9 KiB
/* |
|
* Copyright 2024. Huawei Technologies Co., Ltd. All rights reserved. |
|
* |
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
* you may not use this file except in compliance with the License. |
|
* You may obtain a copy of the License at |
|
* |
|
* http://www.apache.org/licenses/LICENSE-2.0 |
|
* |
|
* Unless required by applicable law or agreed to in writing, software |
|
* distributed under the License is distributed on an "AS IS" BASIS, |
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
* See the License for the specific language governing permissions and |
|
* limitations under the License. |
|
* |
|
*/ |
|
|
|
package harmonyos |
|
|
|
import ( |
|
"crypto/ecdsa" |
|
"crypto/sha256" |
|
"crypto/x509" |
|
"encoding/hex" |
|
"encoding/json" |
|
"encoding/pem" |
|
"errors" |
|
"github.com/cristalhq/jwt/v3" |
|
"io/ioutil" |
|
"time" |
|
) |
|
|
|
type JWTGenerator struct { |
|
} |
|
|
|
type IAPJWTClaims struct { |
|
// Iss Key issuer ID. |
|
Iss string `json:"iss"` |
|
// Aud Expected receiver of the JWT. The value is fixed at iap-v1. |
|
Aud string `json:"aud"` |
|
// Iat Time when the JWT is issued. The value is a UTC timestamp, in seconds. |
|
Iat int64 `json:"iat"` |
|
// Exp Time when the JWT expires. The value is a UTC timestamp, in seconds. exp-iat indicates the validity period of the JWT, which cannot exceed one hour. |
|
Exp int64 `json:"exp"` |
|
// Aid App ID. |
|
Aid string `json:"aid"` |
|
// Digest Hash value of the request body (JSON character string), which is used to verify the integrity of the body. The algorithm is SHA-256. |
|
Digest string `json:"digest"` |
|
} |
|
|
|
const ( |
|
// JWT_PRI_KEY_PATH Private key file path. |
|
JWT_PRI_KEY_PATH = "manifest/config/IAPKey.p8" // TODO: Need to replace it with the actual value. |
|
|
|
// ACTIVE_TIME JWT validity period, which is a UTC timestamp in seconds. The validity period cannot exceed 1 hour. |
|
ACTIVE_TIME_SECOND = 3600 // TODO: Need to replace it with the actual value. |
|
|
|
KID = "f35b90cf-48be-4bb9-bb66-f7e814d5521c" // TODO: Need to replace it with the actual value. |
|
|
|
ISSUER_ID = "002124f1-f9a9-468e-92ea-26561ea9c605" // TODO: Need to replace it with the actual business logic. |
|
|
|
APP_ID = "6917589392953468039" // TODO: Need to replace it with the actual business logic. |
|
) |
|
|
|
func (jwtGenerator *JWTGenerator) GenJWT(bodyMap map[string]interface{}) (string, error) { |
|
privateKeyPEM, err := ioutil.ReadFile(JWT_PRI_KEY_PATH) |
|
if err != nil { |
|
// TODO: Need to replace it with the actual business logic. |
|
return "", err |
|
} |
|
|
|
block, _ := pem.Decode(privateKeyPEM) |
|
if block == nil { |
|
// TODO: Need to replace it with the actual business logic. |
|
return "", errors.New("the key content is empty") |
|
} |
|
|
|
privateKey, err := x509.ParsePKCS8PrivateKey(block.Bytes) |
|
if err != nil { |
|
// TODO: Need to replace it with the actual business logic. |
|
return "", err |
|
} |
|
|
|
ecdsaPrivateKey, ok := privateKey.(*ecdsa.PrivateKey) |
|
if !ok { |
|
// TODO: Need to replace it with the actual business logic. |
|
return "", errors.New("failed to convert private key to *ecdsa.PrivateKey") |
|
} |
|
|
|
signer, err := jwt.NewSignerES(jwt.ES256, ecdsaPrivateKey) |
|
if err != nil { |
|
// TODO: Need to replace it with the actual business logic. |
|
return "", err |
|
} |
|
|
|
payloadJson, err := json.Marshal(bodyMap) |
|
if err != nil { |
|
// TODO: Need to replace it with the actual business logic. |
|
return "", err |
|
} |
|
|
|
hash := sha256.New() |
|
hash.Write(payloadJson) |
|
sha256Sum := hash.Sum(nil) |
|
sha256Hex := hex.EncodeToString(sha256Sum) |
|
|
|
builder := jwt.NewBuilder(signer, jwt.WithKeyID(KID)) // TODO: Need to replace it with the actual business logic. |
|
|
|
signTime := time.Now().UTC().Unix() |
|
claims := IAPJWTClaims{ |
|
Iss: ISSUER_ID, // TODO: Need to replace it with the actual business logic. |
|
Aud: "iap-v1", |
|
Iat: signTime, |
|
Exp: signTime + ACTIVE_TIME_SECOND, |
|
Aid: APP_ID, // TODO: Need to replace it with the actual business logic. |
|
Digest: sha256Hex, |
|
} |
|
|
|
iapJwt, err := builder.Build(claims) |
|
if err != nil { |
|
// TODO: Need replace it with your business logic. |
|
return "", err |
|
} |
|
|
|
return iapJwt.String(), nil |
|
}
|
|
|