Golang动态码MFA
背景概述
当我们对系统进行操作时,往往需要MFA验证码,处于安全考虑MFA又不能给其他人使用,为此我们需要一个工具来提供FMA码给其他人使用。
概念
那么什么是OTP呢? 一次性密码(One Time Password),简称OTP,是只能使用一次的密码。 每次做身份认证时都会生成一个新的密码,在使用一次之后立即失效,不能重复使用。 这种密码只能使用一次,因此即使攻击者能够窃取到密码,也无法再次使用该密码进行身份认证。
参考资料
- kubePi
- gotp
需求实现
生成动态码
这里我们利用已有系统来生成动态码,例如我们的JumpServer
,那么我们如何拿到这个secret呢,我们可以将我们的动态码导出来,然后打开文件即可。
代码案例
package main
import (
"fmt"
"github.com/xlzd/gotp"
)
func main() {
d, _ := GetCode("anRuo")
fmt.Println(d)
}
type Otp struct {
Secret string `json:"secret"`
QrImage string `json:"qrImage"`
Code string `json:"code"`
}
// 直接生成验证码
func GetCode(username string) (otp Otp, err error) {
secret := "111111111111"
otp.Secret = secret
totp := gotp.NewDefaultTOTP(secret)
otp.Code = totp.Now()
return otp, nil
}
❝这样我们就可以将动态码拿到了,然后结合我们的工单系统来实现动态码的申请。
实现动态码
这里我们借鉴JumpServer
的实现方式,将动态码转为图片的形式。
package main
import (
"bytes"
"encoding/base64"
"fmt"
"github.com/skip2/go-qrcode"
"github.com/xlzd/gotp"
)
func main() {
data, _ := GetOtp("www.kubesre.com")
fmt.Println(data)
}
type Otp struct {
Secret string `json:"secret"`
QrImage string `json:"qrImage"`
Code string `json:"code"`
}
func GetOtp(username string) (otp Otp, err error) {
secret := "1111111111"
gotp.RandomSecret(16)
otp.Secret = secret
totp := gotp.NewDefaultTOTP(secret)
uri := totp.ProvisioningUri(username, "anRuo")
subImg, err := qrcode.Encode(uri, qrcode.Medium, 256)
dist := make([]byte, 3000)
base64.StdEncoding.Encode(dist, subImg)
index := bytes.IndexByte(dist, 0)
baseImage := dist[0:index]
otp.QrImage = "data:image/png;base64," + string(baseImage)
return otp, err
}
❝image-20241011144654499image-20241011144742120此时我们就可以将动态码转为图片,然后再结合MFA扫码进行绑定了。
总结
到此我们就大致实现了如何给内部系统添加动态码,以及如何生成动态码了,如果你有更好的方式,欢迎一起交流。