diff --git a/interface-definitions/include/constraint/wireguard-keys.xml.i b/interface-definitions/include/constraint/wireguard-keys.xml.i
new file mode 100644
index 000000000..f59c86087
--- /dev/null
+++ b/interface-definitions/include/constraint/wireguard-keys.xml.i
@@ -0,0 +1,6 @@
+<!-- include start from constraint/wireguard-keys.xml.i -->
+<constraint>
+  <validator name="base64" argument="--decoded-len 32"/>
+</constraint>
+<constraintErrorMessage>Key must be Base64-encoded with 32 bytes in length</constraintErrorMessage>
+<!-- include end -->
diff --git a/interface-definitions/interfaces_wireguard.xml.in b/interface-definitions/interfaces_wireguard.xml.in
index 4f8b6c751..33cb5864a 100644
--- a/interface-definitions/interfaces_wireguard.xml.in
+++ b/interface-definitions/interfaces_wireguard.xml.in
@@ -1,154 +1,145 @@
 <?xml version="1.0"?>
 <interfaceDefinition>
   <node name="interfaces">
     <children>
       <tagNode name="wireguard" owner="${vyos_conf_scripts_dir}/interfaces_wireguard.py">
         <properties>
           <help>WireGuard Interface</help>
           <priority>379</priority>
           <constraint>
             <regex>wg[0-9]+</regex>
           </constraint>
           <constraintErrorMessage>WireGuard interface must be named wgN</constraintErrorMessage>
           <valueHelp>
             <format>wgN</format>
             <description>WireGuard interface name</description>
           </valueHelp>
         </properties>
         <children>
           #include <include/interface/address-ipv4-ipv6.xml.i>
           #include <include/generic-description.xml.i>
           #include <include/interface/disable.xml.i>
           #include <include/port-number.xml.i>
           #include <include/interface/mtu-68-16000.xml.i>
           <leafNode name="mtu">
             <defaultValue>1420</defaultValue>
           </leafNode>
           #include <include/interface/mirror.xml.i>
           #include <include/interface/ipv4-options.xml.i>
           #include <include/interface/ipv6-options.xml.i>
           <leafNode name="fwmark">
             <properties>
               <help>A 32-bit fwmark value set on all outgoing packets</help>
               <valueHelp>
                 <format>number</format>
                 <description>value which marks the packet for QoS/shaper</description>
               </valueHelp>
               <constraint>
                 <validator name="numeric" argument="--range 0-4294967295"/>
               </constraint>
             </properties>
             <defaultValue>0</defaultValue>
           </leafNode>
           <leafNode name="max-dns-retry">
             <properties>
               <help>DNS retries when resolve fails</help>
               <valueHelp>
                 <format>u32:1-15</format>
                 <description>Maximum number of retries</description>
               </valueHelp>
               <constraint>
                 <validator name="numeric" argument="--range 1-15"/>
               </constraint>
             </properties>
             <defaultValue>3</defaultValue>
           </leafNode>
           <leafNode name="private-key">
             <properties>
               <help>Base64 encoded private key</help>
-              <constraint>
-                <validator name="base64"/>
-              </constraint>
-              <constraintErrorMessage>Key is not base64-encoded</constraintErrorMessage>
+              #include <include/constraint/wireguard-keys.xml.i>
             </properties>
           </leafNode>
           <tagNode name="peer">
             <properties>
               <help>peer alias</help>
               <constraint>
                 <regex>[^ ]{1,100}</regex>
               </constraint>
               <constraintErrorMessage>peer alias too long (limit 100 characters)</constraintErrorMessage>
             </properties>
             <children>
               #include <include/generic-disable-node.xml.i>
               #include <include/generic-description.xml.i>
               <leafNode name="public-key">
                 <properties>
-                  <help>base64 encoded public key</help>
-                  <constraint>
-                    <validator name="base64"/>
-                  </constraint>
-                  <constraintErrorMessage>Key is not base64-encoded</constraintErrorMessage>
+                  <help>Base64 encoded public key</help>
+                  #include <include/constraint/wireguard-keys.xml.i>
                 </properties>
               </leafNode>
               <leafNode name="preshared-key">
                 <properties>
-                  <help>base64 encoded preshared key</help>
-                  <constraint>
-                    <validator name="base64"/>
-                  </constraint>
-                  <constraintErrorMessage>Key is not base64-encoded</constraintErrorMessage>
+                  <help>Base64 encoded preshared key</help>
+                  #include <include/constraint/wireguard-keys.xml.i>
                 </properties>
               </leafNode>
               <leafNode name="allowed-ips">
                 <properties>
                   <help>IP addresses allowed to traverse the peer</help>
                   <constraint>
                     <validator name="ip-prefix"/>
                   </constraint>
                   <multi/>
                 </properties>
               </leafNode>
               <leafNode name="address">
                 <properties>
                   <help>IP address of tunnel endpoint</help>
                   <valueHelp>
                     <format>ipv4</format>
                     <description>IPv4 address of remote tunnel endpoint</description>
                   </valueHelp>
                   <valueHelp>
                     <format>ipv6</format>
                     <description>IPv6 address of remote tunnel endpoint</description>
                   </valueHelp>
                   <constraint>
                     <validator name="ip-address"/>
                     <validator name="ipv6-link-local"/>
                   </constraint>
                 </properties>
               </leafNode>
               <leafNode name="host-name">
                 <properties>
                   <help>Hostname of tunnel endpoint</help>
                   <valueHelp>
                     <format>hostname</format>
                     <description>FQDN of WireGuard endpoint</description>
                   </valueHelp>
                   <constraint>
                     <validator name="fqdn"/>
                   </constraint>
                 </properties>
               </leafNode>
               #include <include/port-number.xml.i>
               <leafNode name="persistent-keepalive">
                 <properties>
                   <help>Interval to send keepalive messages</help>
                   <valueHelp>
                     <format>u32:1-65535</format>
                     <description>Interval in seconds</description>
                   </valueHelp>
                   <constraint>
                     <validator name="numeric" argument="--range 1-65535"/>
                   </constraint>
                 </properties>
               </leafNode>
             </children>
           </tagNode>
           #include <include/interface/redirect.xml.i>
           #include <include/interface/per-client-thread.xml.i>
           #include <include/interface/vrf.xml.i>
         </children>
       </tagNode>
     </children>
   </node>
 </interfaceDefinition>
diff --git a/src/validators/base64 b/src/validators/base64
index e2b1e730d..a54168ef7 100755
--- a/src/validators/base64
+++ b/src/validators/base64
@@ -1,27 +1,31 @@
 #!/usr/bin/env python3
 #
-# Copyright (C) 2021 VyOS maintainers and contributors
+# Copyright (C) 2021-2025 VyOS maintainers and contributors
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License version 2 or later as
 # published by the Free Software Foundation.
 #
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 # GNU General Public License for more details.
 #
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import base64
-from sys import argv
+import argparse
 
-if __name__ == '__main__':
-    if len(argv) != 2:
-        exit(1)
-    try:
-        base64.b64decode(argv[1])
-    except:
+parser = argparse.ArgumentParser(description="Validate base64 input.")
+parser.add_argument("base64", help="Base64 encoded string to validate")
+parser.add_argument("--decoded-len", type=int, help="Optional list of valid lengths for the decoded input")
+args = parser.parse_args()
+
+try:
+    decoded = base64.b64decode(args.base64)
+    if args.decoded_len and len(decoded) != args.decoded_len:
         exit(1)
-    exit(0)
+except:
+    exit(1)
+exit(0)