zhangzengfei
2023-09-05 63645d248c765244488cd34dbc1bb6528ca6b7c7
system-service/sys/mosquitto_passwd.go
@@ -1,102 +1,102 @@
package sys
/*
#cgo  LDFLAGS: -lcrypto
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/evp.h>
#include <openssl/opensslv.h>
char* pw_hash(const char *password, unsigned char *salt) {
   const EVP_MD *digest;
   unsigned char *password_hash;
   unsigned int hash_len;
#if OPENSSL_VERSION_NUMBER < 0x10100000L
   EVP_MD_CTX context;
#else
   EVP_MD_CTX *context;
#endif
#if OPENSSL_VERSION_NUMBER < 0x10100000L || OPENSSL_API_COMPAT < 0x10100000L
   OpenSSL_add_all_digests();
#else
   OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS \
         | OPENSSL_INIT_ADD_ALL_DIGESTS \
         | OPENSSL_INIT_LOAD_CONFIG, NULL);
#endif
   digest = EVP_get_digestbyname("sha512");
   if(!digest){
      return NULL;
   }
   password_hash = malloc(64 * sizeof(unsigned char));
#if OPENSSL_VERSION_NUMBER < 0x10100000L
      EVP_MD_CTX_init(&context);
      EVP_DigestInit_ex(&context, digest, NULL);
      EVP_DigestUpdate(&context, password, strlen(password));
      EVP_DigestUpdate(&context, salt, 12);
      EVP_DigestFinal_ex(&context, password_hash, &hash_len);
      EVP_MD_CTX_cleanup(&context);
#else
      context = EVP_MD_CTX_new();
      EVP_DigestInit_ex(context, digest, NULL);
      EVP_DigestUpdate(context, password, strlen(password));
      EVP_DigestUpdate(context, salt, 12);
      EVP_DigestFinal_ex(context, password_hash, &hash_len);
      EVP_MD_CTX_free(context);
#endif
   return password_hash;
}
*/
import "C"
import (
   "encoding/base64"
   "fmt"
   "math/rand"
   "time"
   "unsafe"
)
const EVP_MAX_MD_SIZE = 64
const SALT_LEN = 12
func RandBytes(n int) []byte {
   rand.Seed(time.Now().UnixNano())
   str := "0123456789abcdefghijklmnopqrstuvwxyz"
   bytes := []byte(str)
   var result []byte
   for i := 0; i < n; i++ {
      result = append(result, bytes[rand.Intn(len(bytes))])
   }
   return result
}
/*
   mosquitto生成用户密码的go实现
*/
func OutputNewPassword(username, password string) (text string) {
   saltByte := RandBytes(SALT_LEN)
   salt64 := base64.StdEncoding.EncodeToString(saltByte)
   passwordPtr := C.CString(password)
   defer C.free(unsafe.Pointer(passwordPtr))
   passwordHash := C.pw_hash((*C.char)(unsafe.Pointer(passwordPtr)), (*C.uchar)(unsafe.Pointer(&saltByte[0])))
   defer C.free(unsafe.Pointer(passwordHash))
   hashByte := C.GoBytes(unsafe.Pointer(passwordHash), 64)
   hash64 := base64.StdEncoding.EncodeToString(hashByte)
   text = fmt.Sprintf("%s:$6$%s$%s", username, salt64, hash64)
   return
}
package sys
/*
#cgo  LDFLAGS: -lcrypto
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/evp.h>
#include <openssl/opensslv.h>
char* pw_hash(const char *password, unsigned char *salt) {
   const EVP_MD *digest;
   unsigned char *password_hash;
   unsigned int hash_len;
#if OPENSSL_VERSION_NUMBER < 0x10100000L
   EVP_MD_CTX context;
#else
   EVP_MD_CTX *context;
#endif
#if OPENSSL_VERSION_NUMBER < 0x10100000L || OPENSSL_API_COMPAT < 0x10100000L
   OpenSSL_add_all_digests();
#else
   OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS \
         | OPENSSL_INIT_ADD_ALL_DIGESTS \
         | OPENSSL_INIT_LOAD_CONFIG, NULL);
#endif
   digest = EVP_get_digestbyname("sha512");
   if(!digest){
      return NULL;
   }
   password_hash = malloc(64 * sizeof(unsigned char));
#if OPENSSL_VERSION_NUMBER < 0x10100000L
      EVP_MD_CTX_init(&context);
      EVP_DigestInit_ex(&context, digest, NULL);
      EVP_DigestUpdate(&context, password, strlen(password));
      EVP_DigestUpdate(&context, salt, 12);
      EVP_DigestFinal_ex(&context, password_hash, &hash_len);
      EVP_MD_CTX_cleanup(&context);
#else
      context = EVP_MD_CTX_new();
      EVP_DigestInit_ex(context, digest, NULL);
      EVP_DigestUpdate(context, password, strlen(password));
      EVP_DigestUpdate(context, salt, 12);
      EVP_DigestFinal_ex(context, password_hash, &hash_len);
      EVP_MD_CTX_free(context);
#endif
   return password_hash;
}
*/
import "C"
import (
   "encoding/base64"
   "fmt"
   "math/rand"
   "time"
   "unsafe"
)
const EVP_MAX_MD_SIZE = 64
const SALT_LEN = 12
func RandBytes(n int) []byte {
   rand.Seed(time.Now().UnixNano())
   str := "0123456789abcdefghijklmnopqrstuvwxyz"
   bytes := []byte(str)
   var result []byte
   for i := 0; i < n; i++ {
      result = append(result, bytes[rand.Intn(len(bytes))])
   }
   return result
}
/*
   mosquitto生成用户密码的go实现
*/
func OutputNewPassword(username, password string) (text string) {
   saltByte := RandBytes(SALT_LEN)
   salt64 := base64.StdEncoding.EncodeToString(saltByte)
   passwordPtr := C.CString(password)
   defer C.free(unsafe.Pointer(passwordPtr))
   passwordHash := C.pw_hash((*C.char)(unsafe.Pointer(passwordPtr)), (*C.uchar)(unsafe.Pointer(&saltByte[0])))
   defer C.free(unsafe.Pointer(passwordHash))
   hashByte := C.GoBytes(unsafe.Pointer(passwordHash), 64)
   hash64 := base64.StdEncoding.EncodeToString(hashByte)
   text = fmt.Sprintf("%s:$6$%s$%s", username, salt64, hash64)
   return
}