自定义数据连接器的M语言加密:字符串加密与技术方案问询
Hey there, let's break down your questions about M language (Power Query) encryption and .NET interop:
1. Can M Language encrypt the string "bmVVNG46bmVB"?
First, quick note: that string is actually Base64-encoded (it decodes to nU4n:nEA), which is a form of encoding, not encryption.
Native M doesn't have built-in encryption functions, but you can absolutely encrypt strings by tapping into .NET's cryptography APIs via M's .NET interop capabilities. Here's a working example of encrypting that decoded string using AES:
let EncryptWithAES = (plainText as text, key as text) as text => let // Convert input text to byte arrays plainTextBytes = Text.ToBinary(plainText, TextEncoding.Utf8), // AES requires key lengths of 16, 24, or 32 bytes (for 128/192/256-bit) keyBytes = Text.ToBinary(key, TextEncoding.Utf8), // Initialize AES from .NET library aesType = Type.GetType("System.Security.Cryptography.Aes, System.Security.Cryptography.Primitives"), aesInstance = aesType::Create(), // Set the encryption key _ = aesInstance.set_Key(keyBytes), // Capture the auto-generated IV (needed for decryption later) iv = aesInstance.get_IV(), // Create encryptor and process the text encryptor = aesInstance.CreateEncryptor(), encryptedBytes = encryptor.TransformFinalBlock(plainTextBytes, 0, plainTextBytes.Length), // Combine IV and encrypted data, then convert to Base64 for easy storage/transmission combinedBytes = iv & encryptedBytes, encryptedText = Binary.ToText(combinedBytes, BinaryEncoding.Base64) in encryptedText, // Usage: encrypt the decoded string with a 32-byte key (AES-256) EncryptedOutput = EncryptWithAES("nU4n:nEA", "my32characterlongsecretkey123") in EncryptedOutput
Just make sure your key length matches AES requirements—otherwise you'll get an error. Also, this works in environments where .NET interop is enabled (like Power BI Desktop or Excel Power Query).
2. Can M Language call C# functions?
Yes, definitely! M supports invoking methods from .NET assemblies, which means you can call custom C# functions if you've compiled them into a DLL.
Example: Calling a custom C# encryption function
Suppose you have a C# class library with this helper:
namespace CustomCryptoTools { public static class EncryptionHelper { public static string EncryptString(string plainText, string key) { // Your custom AES encryption logic here byte[] keyBytes = System.Text.Encoding.UTF8.GetBytes(key.PadRight(32).Substring(0,32)); using (var aes = System.Security.Cryptography.Aes.Create()) { aes.Key = keyBytes; var encryptor = aes.CreateEncryptor(aes.Key, aes.IV); byte[] plainBytes = System.Text.Encoding.UTF8.GetBytes(plainText); byte[] encryptedBytes = encryptor.TransformFinalBlock(plainBytes, 0, plainBytes.Length); byte[] combined = aes.IV.Concat(encryptedBytes).ToArray(); return System.Convert.ToBase64String(combined); } } } }
You can reference the compiled DLL in M and call the function like this:
let // Load the custom DLL from your local path customAssembly = Assembly.LoadFrom("C:\\Projects\\CustomCryptoTools\\bin\\Debug\\CustomCryptoTools.dll"), // Get the type of your C# helper class helperType = customAssembly.GetType("CustomCryptoTools.EncryptionHelper"), // Invoke the static EncryptString method encryptedResult = helperType::EncryptString("nU4n:nEA", "mySecretKey123456789012345678901234") in encryptedResult
You can also call system .NET methods directly without custom code, as shown in the AES example earlier.
3. Does M Language have built-in AES/DES standard encryption libraries?
Nope, native M doesn't include built-in encryption libraries for AES, DES, or other standard algorithms. But the good news is you don't need them—you can use .NET's robust System.Security.Cryptography namespace directly from M. This gives you access to all the standard encryption algorithms supported by .NET, including AES, DES, RSA, and more.
Example: DES encryption using .NET in M
If you need DES instead of AES, here's a quick example:
let EncryptWithDES = (plainText as text, key as text) as text => let plainTextBytes = Text.ToBinary(plainText, TextEncoding.Utf8), // DES requires an 8-byte key keyBytes = Text.ToBinary(Text.Start(key, 8), TextEncoding.Utf8), desType = Type.GetType("System.Security.Cryptography.DES, System.Security.Cryptography.Primitives"), desInstance = desType::Create(), _ = desInstance.set_Key(keyBytes), iv = desInstance.get_IV(), encryptor = desInstance.CreateEncryptor(), encryptedBytes = encryptor.TransformFinalBlock(plainTextBytes, 0, plainTextBytes.Length), combinedBytes = iv & encryptedBytes, encryptedText = Binary.ToText(combinedBytes, BinaryEncoding.Base64) in encryptedText, DESOutput = EncryptWithDES("nU4n:nEA", "my8charKey") in DESOutput
Quick note on your provided code: The
bmVVNG46bmVBin yourAuthorizationheader is Base64-encoded credentials for Basic auth. If you want to encrypt this value instead of just encoding it, you'll need to adjust your API call to accept encrypted credentials (since Basic auth expects Base64-encoded plaintext, not encrypted data).
内容的提问来源于stack exchange,提问作者mehwish

